示例#1
0
    def __init__(self) -> None:
        QWidget.__init__(self)

        # self.index stores the index of the latest item which is clicked
        self.index = None

        self.model = QStandardItemModel()

        file_view = QListView()
        file_view.setModel(self.model)
        file_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        file_view.clicked.connect(self.onClicked)
        file_view.doubleClicked.connect(self.onDoubleClicked)

        open_file_button = QPushButton('Open')
        open_file_button.clicked.connect(self.onOpenFile)

        preview_file_button = QPushButton('Preview')
        preview_file_button.clicked.connect(self.onPreviewFile)

        layout = QGridLayout()
        layout.addWidget(file_view, 0, 0, 1, 2)
        layout.addWidget(open_file_button, 1, 0, 1, 1)
        layout.addWidget(preview_file_button, 1, 1, 1, 1)
        layout.setMargin(0)
        self.setLayout(layout)
示例#2
0
class MyWidget(QWidget):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.content_layout = QHBoxLayout()
        self.podcasts_list = QListView()
        self.item_list = QListView()
        self.item_list.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.podcasts_list.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.duration = 0
        self.playtime_label = QLabel()
        self.duration_label = QLabel()
        self.playtime_label.setTextFormat(QtCore.Qt.PlainText)
        self.duration_label.setTextFormat(QtCore.Qt.PlainText)
        self.playtime_label.setText("00:00:00")
        self.playtime_label.setFixedHeight(20)
        self.duration_label.setText("00:00:00")
        self.duration_label.setFixedHeight(20)

        self.progress_bar = QSlider(QtCore.Qt.Horizontal)

        self.content_layout.addWidget(self.podcasts_list)
        self.content_layout.setStretch(0, 2)
        self.content_layout.addWidget(self.item_list)
        self.content_layout.setStretch(1, 8)
        self.download_button = QPushButton("&Download")
        self.play_botton = QPushButton("&Play")

        self.status_layout = QHBoxLayout()
        self.status_layout.addWidget(self.playtime_label)
        self.status_layout.addWidget(self.progress_bar)
        self.status_layout.addWidget(self.duration_label)
        # self.status_layout.addWidget(self.play_botton)
        # self.status_layout.addWidget(self.download_button)

        self.layout = QVBoxLayout()
        self.layout.addLayout(self.content_layout)
        self.layout.addLayout(self.status_layout)

        self.setLayout(self.layout)

    def update_podcasts_list(self, names):
        model = QStringListModel(names)
        self.podcasts_list.setModel(model)

    def update_items_list(self, names):
        model = QStringListModel(names)
        self.item_list.setModel(model)

    def set_progress(self, progress):
        self.progress_bar.setValue(progress)
        self.playtime_label.setText(time_string(progress))

    def set_duration(self, duration):
        self.duration = duration
        self.progress_bar.setRange(0, duration)
        self.duration_label.setText(time_string(duration))
示例#3
0
class FilePicker(QGroupBox):
    def __init__(self, files):
        super().__init__("File Picker")

        self.setLayout(QVBoxLayout())

        self.file_sequence = FileSequence([])

        self._initialize_file_list()

        self.file_sequence = FileSequence(files)
        self._update_file_picker_list([str(file) for file in files])

    def log_file_sequence_status(self):
        logging.debug(f"Current file sequence: {self.file_sequence}")

    def clear_file_list(self):
        self.file_sequence = FileSequence([])
        self.file_list.model().clear()
        self.log_file_sequence_status()

    def _initialize_file_list(self):
        self.file_list = QListView()
        self.file_list.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.layout().addWidget(self.file_list)

        self.file_list.setModel(QStandardItemModel())

        select_files = QPushButton("Select Files")
        select_files.clicked.connect(self._select_files_listener)
        self.layout().addWidget(select_files)

    def _update_file_picker_list(self, file_names):
        model = self.file_list.model()

        # Update File Picker list from files[]
        model.clear()
        for f in range(self.file_sequence.rowCount()):
            item = QStandardItem()
            item.setText(file_names[f])
            model.appendRow(item)

        self.log_file_sequence_status()

    def _select_files_listener(self):
        """Handles selection of files to rename"""

        files = QFileDialog.getOpenFileNames(self, "Select Files", ".")
        self.file_sequence = FileSequence(files[0])

        self._update_file_picker_list(files[0])
示例#4
0
    def __create_vertical_section(self, group_name):
        # Setup layout
        groupbox = QGroupBox(group_name)
        groupbox.setObjectName(group_name)
        vertical_layout = QVBoxLayout()
        groupbox.setLayout(vertical_layout)

        '''
        Add widgets
        '''
        # Add file selection/loading widgets
        file_select_organizer = QHBoxLayout()
        text_input = QLineEdit() # Does this need a name yet?
        file_select_button = QPushButton("...")
        file_select_organizer.addWidget(text_input)
        file_select_organizer.addWidget(file_select_button)
        # Add the section we just made to layout
        vertical_layout.addLayout(file_select_organizer)

        # add listview for excel pages
        excel_label = QLabel("Excel Workbook Pages")
        excel_sheets = QListView()
        excel_sheets.setEditTriggers(QAbstractItemView.NoEditTriggers)
        excel_label_model = QStandardItemModel()
        excel_sheets.setModel(excel_label_model)

        vertical_layout.addWidget(excel_label)
        vertical_layout.addWidget(excel_sheets)


        # add listview for column headers
        variable_label = QLabel("Merge on column:")
        variables = QListView()
        variables.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.columns[group_name] = variables
        variables_model = QStandardItemModel()
        variables.setModel(variables_model)
        vertical_layout.addWidget(variable_label)
        vertical_layout.addWidget(variables)

        '''
        Connect Functions
        '''
        # Connect File dialog to file selection
        file_select_button.clicked.connect(lambda: self.openFileNameDialog(text_input, excel_label_model, group_name))
        # Connect listview to populate listview for column headers
        excel_sheets.clicked.connect(lambda x: self.populateColumns(x, excel_label_model, variables_model, group_name))

        return groupbox
示例#5
0
class SearchDialog(QDialog):
    def __init__(self, subscribe, search):
        super().__init__()
        self.podcast = podcast
        self.setWindowTitle("Search a podcast")
        self.edit = QLineEdit()
        self.result_list = QListView()
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.edit)
        self.layout.addWidget(self.result_list)
        self.setLayout(self.layout)

        self.edit.returnPressed.connect(search)
        self.result_list.doubleClicked.connect(subscribe)
        self.result_list.setEditTriggers(QAbstractItemView.NoEditTriggers)
class TransformationLibrary(QGroupBox):
    def __init__(self, transformation_confirmation):
        super().__init__("Transformation Library")

        self.transformation_configuration = transformation_confirmation

        self.setLayout(QVBoxLayout())

        self._initialize_library()

    def _initialize_library(self):
        self.transformation_list = QListView()
        self.transformation_list.setEditTriggers(
            QAbstractItemView.NoEditTriggers)
        self.layout().addWidget(self.transformation_list)

        self.transformation_list.setModel(QStandardItemModel())

        self.transformation_list.clicked.connect(self.configure_transformation)

        # Populate transformations list
        for transformation in TRANSFORMATIONS:
            transformation_name = transformation.schema["metadata"]["name"]
            transformation_description = transformation.schema["metadata"][
                "description"]

            transformation_element = QStandardItem()
            transformation_element.setText(transformation_name)
            transformation_element.setToolTip(transformation_description)

            self.transformation_list.model().appendRow(transformation_element)

    def configure_transformation(self, x):
        """Resolve selected transformation and pass it to transformation_configuration to display config"""

        model = self.transformation_list.model()
        selected_transformation = TRANSFORMATIONS_BY_NAME[model.data(x)]
        logging.debug(f"Selected transformation: {selected_transformation}")

        self.transformation_configuration.swap_configuration(
            selected_transformation)
示例#7
0
class SourceCodeManager:
    def __init__(self, window):
        self.text_edit = QtGui.QTextEdit(window)
        self.text_edit.setReadOnly(True)
        # FIXME: write an optimized model
        self.traceback = None
        self.traceback_model = QStringListModel()
        self.traceback_view = QListView(window)
        self.traceback_view.setModel(self.traceback_model)
        self.traceback_view.setEditTriggers(
            QtGui.QAbstractItemView.NoEditTriggers)
        window.connect(
            self.traceback_view.selectionModel(),
            QtCore.SIGNAL(
                "selectionChanged(const QItemSelection&, const QItemSelection&)"
            ), self.frame_selection_changed)
        # filename => (lines, mtime)
        self._file_cache = {}
        self.clear()

    def clear(self):
        self._current_file = None
        self._current_lineno = None
        self.traceback_model.setStringList([])
        self.text_edit.setText('')
        self._file_cache.clear()

    def frame_selection_changed(self, selected, unselected):
        indexes = selected.indexes()
        if not indexes:
            return
        row = indexes[0].row()
        frame = self.traceback[row]
        self.show_frame(frame)

    def set_traceback(self, traceback, show_lineno):
        self.traceback = traceback
        if show_lineno:
            lines = [
                '%s:%s' % (frame.filename, frame.lineno) for frame in traceback
            ]
        else:
            lines = [frame.filename for frame in traceback]
        self.traceback_model.setStringList(lines)

    def read_file(self, filename):
        try:
            mtime = os.stat(filename).st_mtime
        except OSError:
            return None

        if filename in self._file_cache:
            text, cache_mtime = self._file_cache[filename]
            if mtime == cache_mtime:
                return text

        print("Read %s content (mtime: %s)" % (filename, mtime))
        with open(filename, 'rb') as fp:
            encoding, lines = detect_encoding(fp.readline)
        lineno = 1
        lines = []
        with io.open(filename, 'r', encoding=encoding) as fp:
            for lineno, line in enumerate(fp, 1):
                lines.append('%d: %s' % (lineno, line.rstrip()))

        text = '\n'.join(lines)
        self._file_cache[filename] = (text, mtime)
        return text

    def load_file(self, filename):
        if filename.startswith("<") and filename.startswith(">"):
            return False
        if self._current_file == filename:
            return True
        text = self.read_file(filename)
        if text is None:
            return False
        self.text_edit.setText(text)
        self._current_file = filename
        self._current_lineno = None
        return True

    def set_line_number(self, lineno):
        if self._current_lineno == lineno:
            return
        self._current_lineno = lineno
        doc = self.text_edit.document()
        # FIXME: complexity in O(number of lines)?
        block = doc.findBlockByLineNumber(lineno - 1)
        cursor = QTextCursor(block)
        cursor.select(QTextCursor.BlockUnderCursor)
        # FIXME: complexity in O(number of lines)?
        self.text_edit.setTextCursor(cursor)

    def show_frame(self, frame):
        filename = frame.filename
        if not self.load_file(filename):
            self._current_file = None
            self.text_edit.setText('')
            return
        if frame.lineno > 0:
            self.set_line_number(frame.lineno)
class LayersList(QWidget):
    '''
    LayerList class which acts as collapsable list.
    '''
    def __init__(self, name, layers, filter, expand=True):
        super().__init__()
        self.setWindowModality(QtCore.Qt.WindowModal)
        self.currently_expanded = True
        self.main_layout = QVBoxLayout()
        self.main_layout.setMargin(0)
        self.main_layout.setSpacing(0)
        self.main_layout.setContentsMargins(0, 0, 0, 0)

        self.expand_button = QPushButton(name)
        self.expand_button.setToolTip(f"List of {name} Layers")
        self.expand_button.setIcon(
            QIcon(os.path.join(PATH, 'LayersList_Down.png')))

        self.layer_list = QListView()
        self.layer_list.setDragEnabled(True)
        self.layer_list.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.layer_list.setWrapping(False)
        self.layer_list.setViewMode(self.layer_list.ListMode)

        self.container_model = QStandardItemModel()
        self.model = QSortFilterProxyModel()
        self.model.setSourceModel(self.container_model)
        self.model.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        #self.model.cas
        filter.textChanged.connect(self.filter_model)

        for l in layers:
            self.container_model.appendRow(
                QStandardItem(
                    QIcon(os.path.join(PATH, 'LayersList_Layer_Icon.png')), l))

        self.layer_list.setModel(self.model)

        self.main_layout.addWidget(self.expand_button, 0, Qt.AlignTop)
        self.main_layout.addWidget(self.layer_list, 0, Qt.AlignTop)
        self.expand_button.clicked.connect(self.expand)

        self.setLayout(self.main_layout)
        self.resized_size = len(layers) * (self.layer_list.sizeHintForRow(0) +
                                           self.layer_list.frameWidth())

        self.layer_list.setMaximumHeight(self.resized_size)
        self.layer_list.setMinimumHeight(self.resized_size)

        self.setMinimumWidth(self.layer_list.frameWidth())

        self.set_styling()

        if not expand:
            self.expand()

    @QtCore.Slot()
    def expand(self):
        if self.currently_expanded:
            self.layer_list.setMinimumHeight(0)
            self.currently_expanded = False
            self.expand_button.setIcon(
                QIcon(os.path.join(PATH, 'LayersList_Up2.png')))
            self.layer_list.setMaximumHeight(0)
        else:
            self.layer_list.setMinimumHeight(self.resized_size)
            self.currently_expanded = True
            self.expand_button.setIcon(
                QIcon(os.path.join(PATH, 'LayersList_Down.png')))
            self.layer_list.setMaximumHeight(self.resized_size)

    def set_styling(self):
        self.setStyleSheet('''
                           background-color:white;
                           ''')
        self.expand_button.setStyleSheet('''
                                        background-color:#d6d2d2;
                                        text-align:left;
                                        ''')

    @QtCore.Slot()
    def filter_model(self, text):
        self.show()
        self.model.setFilterRegExp(QRegExp(text, QtCore.Qt.CaseInsensitive))
        if not self.currently_expanded:
            self.expand()
        if self.model.rowCount() == 0:
            self.hide()
示例#9
0
class SymbolViewFrame(QWidget):

    # --- Init methods ---

    def __init__(self, config):
        """
        Symbols and Labels view frame

        :param config: application configuration file
        """
        QWidget.__init__(self)

        self.setFixedSize(QSize(320, 330))
        self.setWindowTitle("DigiQt - Symbols")

        self.config = config

        self.lab_label = QLabel("Labels")
        self.lab_label.setAlignment(Qt.AlignCenter)
        self.lab_symbols = QLabel("Symbols")
        self.lab_symbols.setAlignment(Qt.AlignCenter)

        self.sig_symbol_goto = None  # pushed by the controler

        # Initialization of the lists
        self.labels_view = QListView()
        self.labels_view.setFixedSize(QSize(150, 300))
        self.labels_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.labels_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.dm_labels = QStandardItemModel(self.labels_view)

        self.symbols_view = QListView()
        self.symbols_view.setFixedSize(QSize(150, 300))
        self.symbols_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.symbols_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.dm_symbols = QStandardItemModel(self.symbols_view)

        self.init_labels([])
        self.init_symbols([])

        self.labels_view.clicked.connect(self.on_label_changed)
        self.symbols_view.clicked.connect(self.on_symbol_changed)

        self.__set_layout()
        self.setStyleSheet(style.get_stylesheet("listviews_frame"))

    def init_labels(self, list_labels):
        """
        Initiates the data model for the labels

        :param list_labels: list of labels
        """
        self.__init_view(self.labels_view, self.dm_labels, list_labels)

    def init_symbols(self, list_symbols):
        """
        Initiates the data model for the symbols

        :param list_symbols: list of symbols
        """
        self.__init_view(self.symbols_view, self.dm_symbols, list_symbols)

    def __init_view(self, list_view, data_model, objects_list):
        """
        Initiates the view given the data_model and the objects to add in it.

        :type list_view: QListView
        :type data_model: QStandardItemModel
        :type objects_list: list
        """
        data_model.clear()

        for l in objects_list:
            data_model.appendRow(QStandardItem(l))

        list_view.setModel(data_model)

    def __set_layout(self):
        """
        Creates this Widget's Layout
        """
        box = QGridLayout()
        box.setContentsMargins(0, 0, 0, 0)

        box.addWidget(self.lab_label, 0, 0)
        box.addWidget(self.labels_view, 1, 0)
        box.addWidget(self.lab_symbols, 0, 1)
        box.addWidget(self.symbols_view, 1, 1)

        self.setLayout(box)

    def on_label_changed(self, item):
        """
        Callback method for the label change signal

        :param item: new item selected
        :type item: QItemSelection
        """
        text = item.data()
        if text:
            self.sig_symbol_goto.emit(text)
            self.place_search_text(text)

    def on_symbol_changed(self, item):
        """
        Callback method for the symbol change signal
        :param item: new item selected
        :type item: QItemSelection
        """
        text = item.data()
        if text:
            self.sig_symbol_goto.emit(text)
            self.place_search_text(text)

    def place_search_text(self, text):
        """
        Updates the searched value in the editor search field.

        :param text: label or symbol to place as search text
        """
        pass

    def __retrieve_text(self, data_model, item):
        """
        Gets the text with the specified data model from a QItemSelection

        :type item: QItemSelection
        :type data_model: QStandardItemModel
        :rtype: str
        """
        selection = item.indexes()
        if selection:
            return data_model.item(QModelIndex(selection[0]).row()).text()

    # --- Close handler ---

    def closeEvent(self, event):
        """
        Event called upon a red-cross click.
        """
        self.on_close()

    def on_close(self):
        """
        Reroot this method in the Main Frame in order to Updates the execution frame's open editor icon and tooltip
        :return:
        """
        pass
示例#10
0
class PipelineEditor(QGroupBox):
    def __init__(self, file_picker):
        super().__init__("Pipeline Editor")

        self.setLayout(QVBoxLayout())

        self.file_picker = file_picker

        self.pipeline = Pipeline()
        self.pipelineView = QListView()
        self.pipelineView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.pipelineView.setModel(QStandardItemModel())

        self.layout().addWidget(self.pipelineView)

        # === BUTTON CONTAINER ===
        button_rows = QWidget()
        self.layout().addWidget(button_rows)
        button_rows_layout = QVBoxLayout(button_rows)
        button_rows_layout.setContentsMargins(0, 0, 0, 0)

        # === ROW 1 ===
        row_1 = QWidget()
        button_rows_layout.addWidget(row_1)
        row_1_layout = QHBoxLayout(row_1)
        row_1_layout.setContentsMargins(0, 0, 0, 0)

        self.moveUpButton = QPushButton("Move Up")
        row_1_layout.addWidget(self.moveUpButton)
        self.moveUpButton.clicked.connect(self._move_up_listener)

        self.moveDownButton = QPushButton("Move Down")
        row_1_layout.addWidget(self.moveDownButton)
        self.moveDownButton.clicked.connect(self._move_down_listener)

        self.deleteButton = QPushButton("Delete")
        row_1_layout.addWidget(self.deleteButton)
        self.deleteButton.clicked.connect(self._delete_listener)

        # === ROW 2 ===
        row_2 = QWidget()
        button_rows_layout.addWidget(row_2)
        row_2_layout = QHBoxLayout(row_2)
        row_2_layout.setContentsMargins(0, 0, 0, 0)

        self.applyButton = QPushButton("Apply Pipeline")
        row_2_layout.addWidget(self.applyButton)
        self.applyButton.clicked.connect(self._apply_pipeline_listener)

        self.update_pipeline_view()

    def update_pipeline_view(self):
        logging.debug(self.pipeline)
        model = self.pipelineView.model()
        model.clear()

        for t in range(self.pipeline.rowCount()):
            item = QStandardItem()
            item.setText(repr(self.pipeline.data(t)))
            model.appendRow(item)

    def _modify_transformation_listener(self):
        # TODO
        raise NotImplementedError

    def _move_up_listener(self):
        try:
            to_move = self.pipelineView.selectionModel().selectedIndexes(
            )[0].row()
            if to_move < 1:
                return
            self.pipeline.move_transformation_up(to_move)
            self.update_pipeline_view()
            self.pipelineView.setCurrentIndex(self.pipelineView.model().index(
                to_move - 1, 0))
        except IndexError:
            return

    def _move_down_listener(self):
        try:
            to_move = self.pipelineView.selectionModel().selectedIndexes(
            )[0].row()
            if to_move > self.pipelineView.model().rowCount() - 2:
                return
            self.pipeline.move_transformation_down(to_move)
            self.update_pipeline_view()
            self.pipelineView.setCurrentIndex(self.pipelineView.model().index(
                to_move + 1, 0))
        except IndexError:
            return

    def _delete_listener(self):
        try:
            to_delete = self.pipelineView.selectionModel().selectedIndexes(
            )[0].row()
            self.pipeline.remove_transformation(to_delete)
            self.update_pipeline_view()
            if to_delete > self.pipelineView.model().rowCount() - 1:
                self.pipelineView.setCurrentIndex(
                    self.pipelineView.model().index(to_delete - 1, 0))
            else:
                self.pipelineView.setCurrentIndex(
                    self.pipelineView.model().index(to_delete, 0))
        except IndexError:
            return

    def _apply_pipeline_listener(self):
        # Check that at least one transformation has been added to the pipeline
        if self.pipeline.rowCount() == 0:
            no_transformations_messagebox = QMessageBox(self)
            no_transformations_messagebox.setText(
                "ERROR: No transformations selected")
            no_transformations_messagebox.exec_()
            return

        file_sequence = self.file_picker.file_sequence.files

        # Check that at least one file has been added to the file sequence
        if len(file_sequence) == 0:
            no_files_messagebox = QMessageBox(self)
            no_files_messagebox.setText("ERROR: No files selected")
            no_files_messagebox.exec_()
            return

        transformed_sequence = self.pipeline.resolve(file_sequence)

        before_after = list(zip(file_sequence, transformed_sequence))

        preview_text_lines = []
        for rename in before_after:
            preview_text_lines.append(f"{rename[0].name} -> {rename[1].name}")
        preview_text = "\n".join(preview_text_lines)

        confirmation = QMessageBox(self)
        confirmation.setText("Are you sure you want to apply the pipeline?")
        confirmation.setDetailedText(preview_text)
        confirmation.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        confirmation.setDefaultButton(QMessageBox.No)
        ret = confirmation.exec_()

        if ret == int(QMessageBox.Yes):
            for rename in before_after:
                from_path = rename[0]
                to_path = rename[1]

                shutil.move(str(from_path), str(to_path))
            self.file_picker.clear_file_list()