def __init__(self):
        QDockWidget.__init__(self, "File Menager")
        self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)

        model = QFileSystemModel()
        model.setRootPath(QDir.currentPath())

        tree = QTreeView()
        tree.setModel(model)
        self.setWidget(tree)
Beispiel #2
0
 def init_file_system_tree(self):
     model = QFileSystemModel(nameFilterDisables=False)
     model.setRootPath("Desktop")
     model.setNameFilters(["*.txt", "*.csv"])
     self.ui.browserTreeView.setModel(model)
     self.ui.browserTreeView.setRootIndex(model.index("Desktop"))
     self.ui.browserTreeView.hideColumn(1)
     self.ui.browserTreeView.hideColumn(2)
     self.ui.browserTreeView.hideColumn(3)
     self.ui.browserTreeView.doubleClicked.connect(self.onClicked)
Beispiel #3
0
 def open_directory(self, dir):
     model = QFileSystemModel(self.ui.fileTreeView)
     model.setNameFilters(["*.jpg", "*.JPG"])
     model.setRootPath(dir)
     self.ui.fileTreeView.setModel(model)
     self.ui.fileTreeView.setRootIndex(model.index(dir))
     self.ui.fileTreeView.header().setStretchLastSection(False)
     self.ui.fileTreeView.header().setSectionResizeMode(0, QHeaderView.Stretch)
     self.ui.fileTreeView.selectionModel().selectionChanged.connect(self.current_file_changed)
     self.ui.fileTreeView.hideColumn(1)
     self.ui.fileTreeView.hideColumn(2)
     self.ui.fileTreeView.hideColumn(3)
     self.ui.fileTreeView.hideColumn(4)
Beispiel #4
0
class App(QWidget):
    '''The FolderMaker base class'''
    def __init__(self, root_path, conf):
        super().__init__()
        self.title = 'FolderMaker'
        self.root_path = root_path
        self.conf = conf
        self.init_ui()

    def on_btn(self):
        '''Creates buttons on click'''
        basedir = ROOT_PATH
        try:
            create_dirs(
                self.conf, basedir,
                range(int(self.start_box.text()), int(self.stop_box.text())))
        except ValueError:
            msg = QMessageBox()
            msg.setText('Error! Invalid numbers in text boxes!')
            msg.exec()
        except FileExistsError as file_ex:
            msg = QMessageBox()
            msg.setText(
                f'Error! Directory already exists! Exception: {str(file_ex)}')
            msg.exec()

    def init_ui(self):
        '''Initializes the UI'''
        self.setWindowTitle(self.title)
        self.model = QFileSystemModel()
        self.model.setRootPath(ROOT_PATH)
        self.tree = QTreeView()
        self.tree.setModel(self.model)
        self.tree.setRootIndex(self.model.index(self.root_path))
        self.start_box = QLineEdit()
        self.stop_box = QLineEdit()
        self.start_box.setValidator(QIntValidator())
        self.stop_box.setValidator(QIntValidator())
        self.make_btn = QPushButton("Create Project Folders")
        self.make_btn.clicked.connect(self.on_btn)
        layout = QVBoxLayout()
        layout.addWidget(self.tree)
        subgrid = QGridLayout()
        subgrid.addWidget(self.start_box, 0, 1)
        subgrid.addWidget(self.stop_box, 1, 1)
        subgrid.addWidget(QLabel('From (inc.): '), 0, 0)
        subgrid.addWidget(QLabel('To (not inc.): '), 1, 0)
        layout.addLayout(subgrid)
        layout.addWidget(self.make_btn)
        self.setLayout(layout)
        self.show()
Beispiel #5
0
class FSLineEdit(QLineEdit):
    """
    A line edit with auto completion for file system folders.
    """
    def __init__(self, parent=None):
        QLineEdit.__init__(self, parent)
        self.fsmodel = QFileSystemModel()
        self.fsmodel.setRootPath("")
        self.completer = QCompleter()
        self.completer.setModel(self.fsmodel)
        self.setCompleter(self.completer)
        self.fsmodel.setFilter(QDir.Drives | QDir.AllDirs | QDir.Hidden |
                               QDir.NoDotAndDotDot)

    def setPath(self, path):
        self.setText(path)
        self.fsmodel.setRootPath(path)
class FileSystemView(QWidget):
    def __init__(self, dir_path):
        super().__init__()
        # appWidth = 800
        # appHeight = 300
        self.setWindowTitle('File System Viewer')
        # self.setGeometry(300, 300, appWidth, appHeight)

        self.model = QFileSystemModel()
        self.model.setRootPath(dir_path)
        self.tree = QTreeView()
        self.tree.setModel(self.model)
        self.tree.setRootIndex(self.model.index(dir_path))
        self.tree.setColumnWidth(0, 250)
        self.tree.setAlternatingRowColors(True)

        layout = QVBoxLayout()
        layout.addWidget(self.tree)
        self.setLayout(layout)
Beispiel #7
0
    def sd_path(self, startup, width):
        """Allows the user to specify the path to their SD card via
        their OS file explorer dialog. Note, nothing is done to ensure
        that the location selected is actually an SD card.
        Currently triggered via a menu action.

        startup: True if this is being called during startup, False
                 otherwise.
        width: The width of the main window.
        """

        if not startup:
            input_dir = QFileDialog.getExistingDirectory(
                None, "Select an SD Card:", expanduser("~"))
            if input_dir != "" and os.path.isdir(input_dir):
                if "/" in input_dir and platform.system().lower() == "windows":
                    # THIS IS NEEDED FOR WINDOWS.
                    # This comes from a bug with QFileDialog returning the
                    # wrong path separator on Windows for some odd reason.
                    input_dir = input_dir.split("/")[0]
                elif "/" in input_dir:
                    # OSX case.
                    pass
                else:
                    input_dir = input_dir.split(os.path.sep)[0]
                self.sd_root = str(input_dir)
                self.export_dir = os.path.join(self.sd_root, "to_zoia")
                self.ui.tab_sd.setEnabled(True)
            else:
                self.ui.tab_sd.setEnabled(False)
                self.ui.tabs.setCurrentIndex(1)

        # Setup the SD card tree view for the SD Card tab.
        self.ui.statusbar.showMessage("SD card location successfully set.",
                                      timeout=5000)
        model = QFileSystemModel()
        model.setRootPath(self.sd_root)
        self.ui.sd_tree.setModel(model)
        self.ui.sd_tree.setRootIndex(model.setRootPath(self.sd_root))
        self.ui.sd_tree.setColumnWidth(0, width // 2)
        for i in range(1, 4):
            self.ui.sd_tree.setColumnHidden(i, True)
Beispiel #8
0
def model_view():
    app = QApplication()
    splitter = QSplitter()

    model = QFileSystemModel()
    model.setRootPath(QDir.currentPath())
    parentIndex = model.index(QDir.currentPath())

    tree = QTreeView(splitter)
    tree.setModel(model)
    tree.setRootIndex(parentIndex)

    list = QListView(splitter)
    list.setModel(model)
    list.setRootIndex(parentIndex)

    table = QTableView(splitter)
    table.setModel(model)
    table.setRootIndex(parentIndex)

    splitter.setWindowTitle("Two views onto the same file system model")
    splitter.show()
    app.exec_()
Beispiel #9
0
    def __init__(self):

        QMainWindow.__init__(self)
        self.setupUi(self)

        # Viewing the filesystem tree

        treeModel = QFileSystemModel()
        treeModel.setRootPath(QDir.currentPath())

        # We only show the name/path

        view = self.treeview_os_directories
        view.setModel(treeModel)
        view.model().sort(1, order=Qt.DescendingOrder)
        view.hideColumn(1)
        view.hideColumn(2)
        view.hideColumn(3)
        view.setColumnWidth(0, 10)
        view.setColumnWidth(1, 1)
        view.setColumnWidth(2, 1)

        # Setting a contextual menu

        self.treeview_os_directories.customContextMenuRequested.connect(
            self.openMenuDirectories)

        # Adding actions

        self.actionSortie.triggered.connect(self.close)

        # The selected directories/files (search list) will be stored in a global list

        global dir_list

        for dir in dir_list:
            self.listWidget_selected_directories.addItem(QListWidgetItem(dir))
Beispiel #10
0
class TreeView(QWidget):
    def __init__(self, path=None):

        super(TreeView, self).__init__()

        self.model = QFileSystemModel()

        if path:
            self.selectedPath = path
            self.model.setRootPath(self.selectedPath)
        else:
            self.selectedPath = QDir.currentPath()
            self.model.setRootPath(self.selectedPath)

        mainLayout = QVBoxLayout()
        mainLayout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(mainLayout)

        self.tree = QTreeView()
        self.tree.setModel(self.model)
        self.tree.setRootIndex(self.model.index(self.selectedPath))
        self.tree.setColumnHidden(1, True)
        self.tree.setColumnHidden(2, True)
        self.tree.setColumnHidden(3, True)
        mainLayout.addWidget(self.tree)

    def changePath(self, path):

        self.selectedPath = path

        self.tree.setModel(None)

        self.model.setRootPath(self.selectedPath)
        self.model.setNameFilters(
            ["*.png", "*.jpg", "*.bmp", "*.svg", "*.tiff", "*.gif"])

        self.tree.setModel(self.model)
        self.tree.setRootIndex(self.model.index(self.selectedPath))
        self.tree.setColumnHidden(1, True)
        self.tree.setColumnHidden(2, True)
        self.tree.setColumnHidden(3, True)

        self.repaint()
Beispiel #11
0
    def __initFilesSystemModel__(self):
        model = QFileSystemModel()
        model.setRootPath(r'C:')
        model.setReadOnly(True)

        return model
Beispiel #12
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # SET => App Icon
        self.icon = QIcon("img/iconXLNK.png")
        # End

        self.tree_view = None
        self.file_system_model = None

        # SET => Window Icon
        self.setWindowIcon(self.icon)
        # End

        # WSET => Window Title
        self.setWindowTitle("XLNK | Data Manager")
        # End

        # Menus
        self.menu = self.menuBar()
        self.file_menu = self.menu.addMenu("&File")
        self.edit_menu = self.menu.addMenu("&Edit")
        self.view_menu = self.menu.addMenu("&View")
        self.help_menu = self.menu.addMenu("&Help")
        # End

        # ===================
        # Menu Button Actions

        # Exit QAction
        exit_action = QAction("Exit", self)
        exit_action.setShortcut(QKeySequence.Quit)
        exit_action.triggered.connect(self.close)
        self.file_menu.addAction(exit_action)
        # End
        # End

        # Tool Bar
        toolbar = QToolBar(self)
        self.addToolBar(toolbar)

        # delete action on toolbar
        delete_action_tb = QAction("DELETE TABLE ROW", self)
        delete_action_tb.setStatusTip("Obrisi Red U Tabeli")
        delete_action_tb.triggered.connect(self.delete_table_row_tb)
        toolbar.addAction(delete_action_tb)

        # Dock Widget
        dock_widget = QDockWidget("EXPLORER", self)
        # File System Model
        self.file_system_model = QFileSystemModel()
        self.file_system_model.setRootPath(QDir.currentPath())
        # SET => Tree View MOdel
        self.tree_view = QTreeView()
        self.tree_view.setModel(self.file_system_model)
        self.tree_view.setRootIndex(
            self.file_system_model.index(QDir.currentPath() + "/data"))
        self.tree_view.clicked.connect(self.file_clicked_handler)
        dock_widget.setWidget(self.tree_view)
        dock_widget.setFloating(False)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock_widget)

        # QLabel
        qlabel = QLabel(self)
        qlabel.setText("Welcome to XLNK.")

        # Central Widget
        self.clicked_file = None

        self.setCentralWidget(qlabel)

        self.showMaximized()

    # ToolBar Functions
    # TODO
    def delete_table_row_tb(self):
        print("Ugraditi funkciju za brisanje reda iz tabele.")

    def file_clicked_handler(self, index):
        index = self.tree_view.currentIndex()
        file_clicked_param = os.path.basename(
            self.file_system_model.filePath(index))
        self.clicked_file = file_clicked_param
        self.status_bar = QStatusBar(self)
        self.status_bar.showMessage(
            "File Selected: {}".format(file_clicked_param), 3000)
        self.setStatusBar(self.status_bar)
        self.workspace_widget = WorkSpaceWidget(self, self.clicked_file)
        self.setCentralWidget(self.workspace_widget)
Beispiel #13
0
class DownloadDirTreeWidget(QWidget):
    def __init__(self, root_path) -> None:
        QWidget.__init__(self)

        # self.index stores the index of the latest item which is clicked
        # self.root_path is the path to the folder currently showing
        self.index = None
        self.root_path = os.path.abspath(root_path)

        self.dir_view = QTreeView()
        self.model = QFileSystemModel(self.dir_view)
        self.model.setRootPath(self.root_path)
        self.dir_view.clicked.connect(self.onFileItemClicked)
        self.dir_view.doubleClicked.connect(self.onFileItemDoubleClicked)
        self.dir_view.setModel(self.model)
        self.dir_view.setRootIndex(self.model.index(self.root_path))

        open_button = QPushButton("Open")
        open_button.clicked.connect(self.openFile)

        open_in_file_explorer_button = QPushButton("Open in File Explorer")
        open_in_file_explorer_button.clicked.connect(self.openInFileExplorer)

        self.root_path_line_edit = QLineEdit(self.root_path)
        self.root_path_line_edit.returnPressed.connect(
            self.onChangeLineEditReturned)
        self.root_path_line_edit.setSizePolicy(QSizePolicy.Minimum,
                                               QSizePolicy.Minimum)
        self.root_path_line_edit.adjustSize()

        change_path_button = QPushButton('Change Directory')
        change_path_button.clicked.connect(self.onChangeButtonClicked)

        addressCompleter = QCompleter()
        addressCompleter.setModel(self.model)
        self.root_path_line_edit.setCompleter(addressCompleter)

        # Set layout
        layout = QGridLayout()
        layout.addWidget(self.root_path_line_edit, 0, 0, 1, 1)
        layout.addWidget(change_path_button, 0, 1, 1, 1)
        layout.addWidget(self.dir_view, 1, 0, 1, 2)
        layout.addWidget(open_button, 2, 0, 1, 1)
        layout.addWidget(open_in_file_explorer_button, 2, 1, 1, 1)
        layout.setMargin(0)
        self.setLayout(layout)

    def setRootPath(self, root_path):
        self.root_path = os.path.abspath(root_path)

    def openFile(self):
        if self.index is not None:
            file_path = self.model.filePath(self.index).replace('/', '\\')
            is_dir = self.model.isDir(self.index)
            # If is file, open with default program
            # If is directory, open with file explorer
            if is_dir is False:
                os.startfile(file_path, 'open')
            else:
                subprocess.run(['explorer', file_path])

    def openInFileExplorer(self):
        if self.index is None:
            file_path = self.model.filePath(self.index).replace('/', '\\')
            subprocess.run(['explorer', '/select,', file_path])

    def onFileItemClicked(self, index):
        # When clicked, resize and update self.index
        self.dir_view.resizeColumnToContents(0)
        self.index = index

    def onFileItemDoubleClicked(self, index):
        # When double clicked, update self.index and open the file directly
        self.index = index
        if self.sender().model().isDir(index) is False:
            self.openFile()

    def onChangeButtonClicked(self):
        new_path = QFileDialog.getExistingDirectory(self, 'Change Directory',
                                                    self.root_path)
        self.changeRootPath(new_path)

    def onChangeLineEditReturned(self):
        new_path = self.root_path_line_edit.text()
        if os.path.isdir(new_path):
            self.changeRootPath(new_path)
        else:
            subprocess.run(['explorer', new_path])
            self.root_path_line_edit.setText(self.root_path)

    def changeRootPath(self, new_path: str):
        if os.path.exists(new_path):
            self.root_path = os.path.abspath(new_path)
            self.dir_view.setRootIndex(self.model.index(self.root_path))
            self.root_path_line_edit.setText(self.root_path)
Beispiel #14
0
    def init_ui(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.top, self.left, self.width, self.height)

        # layout root of application
        main_layout = QVBoxLayout(self)
        self.setLayout(main_layout)

        # to set the model of tree
        model = QFileSystemModel()
        model.setRootPath("/home/denison/Downloads/music")
        model.setNameFilters(['*.mp3', '*.m4a', '*.flac'])
        model.setNameFilterDisables(False)

        self.tree = QTreeView()
        self.tree.setModel(model)
        self.tree.setAnimated(True)
        self.tree.setColumnWidth(0, 500)

        file_layout = QHBoxLayout()
        label_file = QLabel('file/directory')
        text_file = QLineEdit()
        btn_load = QPushButton('load')
        file_layout.addWidget(label_file)
        file_layout.addWidget(text_file)
        file_layout.addWidget(btn_load)

        grid_info_layout = QGridLayout()
        # strings to labels
        self.labels = [
            'ARTIST', 'ALBUMARTIST', 'ALBUM', 'TITLE', 'GENRE', 'DATE'
        ]

        # line edits to tags
        self.text_artist = QLineEdit('ARTIST')
        self.text_album = QLineEdit('ALBUM')
        self.text_album_artist = QLineEdit('ALBUMARTIST')
        self.text_title = QLineEdit('TITLE')
        self.text_genre = QLineEdit('GENRE')
        self.text_date = QLineEdit('DATE')

        self.text_tags = [
            self.text_artist, self.text_album_artist, self.text_album,
            self.text_title, self.text_genre, self.text_date
        ]

        for text in self.text_tags:
            text.setEnabled(False)
            #text.textChanged.connect(self.enable_save)

        # labels
        for label, i in zip(self.labels, range(6)):
            grid_info_layout.addWidget(QLabel(label), i, 0)

        # cb_artist = QCheckBox()
        # cb_album_artist = QCheckBox()
        # cb_album = QCheckBox()
        # cb_title = QCheckBox()
        # cb_genre = QCheckBox()
        # cb_date = QCheckBox()
        # self.checkboxes = [
        #     cb_artist, cb_album_artist, cb_album,
        #     cb_title, cb_genre, cb_date
        # ]

        # for cb in self.checkboxes:
        #     cb.setText('editar')

        # cb_artist.stateChanged.connect(lambda: self.enable_tag_edit(self.text_artist))
        # cb_album_artist.stateChanged.connect(lambda: self.enable_tag_edit(self.text_album_artist))
        # cb_album.stateChanged.connect(lambda: self.enable_tag_edit(self.text_album))
        # cb_title.stateChanged.connect(lambda: self.enable_tag_edit(self.text_title))
        # cb_genre.stateChanged.connect(lambda: self.enable_tag_edit(self.text_genre))
        # cb_date.stateChanged.connect(lambda: self.enable_tag_edit(self.text_date))

        for i, text in zip(range(6), self.text_tags):
            grid_info_layout.addWidget(text, i, 1)

        # for cb, i in zip(self.checkboxes, range(6)) :
        #     grid_info_layout.addWidget(cb, i, 2)

        action_layout = QHBoxLayout()
        btn_exit = QPushButton('Exit')
        self.btn_save = QPushButton('save changes')
        self.btn_save.setDisabled(True)
        action_layout.addWidget(btn_exit)
        action_layout.addWidget(self.btn_save)

        #main_layout.addLayout(file_layout)
        main_layout.addWidget(self.tree)
        main_layout.addLayout(grid_info_layout)
        main_layout.addLayout(action_layout)

        btn_load.clicked.connect(self.open_file)
        btn_exit.clicked.connect(self.close_application)
        self.btn_save.clicked.connect(self.edit_tags)
        self.tree.doubleClicked.connect(self.get_selected_file)
        self.show()
Beispiel #15
0
class Dock(QDockWidget):
    def __init__(self, title, central_widget, parent=None):
        super().__init__(title, parent=parent)
        self.central_widget = central_widget

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.tree = QTreeView()
        self.tree.pressed.connect(self.setIndex)
        self.index_ = None

        self.db_tree = QTreeView()
        self.db_tree.setAnimated(True)
        self.db_model = QStandardItemModel()
        self.db_model.setHorizontalHeaderLabels(["Database"])
        self.db_root = self.db_model.invisibleRootItem()

        self.dbs = []

    def contextMenuEvent(self, event):
        contextMenu = QMenu(self)
        deleteFile = contextMenu.addAction("Delete File")
        action = contextMenu.exec_(self.mapToGlobal(event.pos()))
        if action == deleteFile:
            alert = QMessageBox()
            alert.setWindowTitle("Action Dialog")
            alert.setText("Are you sure you want to delete this file?")
            alert.setStandardButtons(QMessageBox.No | QMessageBox.Yes)
            alert.setDefaultButton(QMessageBox.No)
            response = alert.exec_()
            if response == QMessageBox.No:
                contextMenu.close()
            else:
                file_name = self.model.filePath(
                    self.index_).split("storage/")[1]
                os.remove(self.model.filePath(self.index_))
                os.remove(
                    self.model.filePath(self.index_).split("/storage")[0] +
                    "/meta/" + file_name + "_metadata.json")
                contextMenu.close()

    def setIndex(self, index):
        self.index_ = index

    def tree_init(self):
        self.tree.setModel(self.model)
        self.tree.setRootIndex(
            self.model.index(QDir.currentPath() + "/model/storage"))

        self.tree.clicked.connect(self.file_clicked)

        self.setWidget(self.tree)

    def init_db_tree(self):
        self.clear_tree()
        self.db_tree.setModel(self.db_model)
        self.db_tree.clicked.connect(self.table_clicked)
        self.setWidget(self.db_tree)
        self.connected_dbs()

    def file_clicked(self, index):
        file_path = self.model.filePath(index)
        workspace = Workspace(file_path, self.central_widget)
        self.central_widget.add_tab(
            workspace,
            QIcon("view/images/dark/baseline_notes_black_48dp.png"),
            file_path.split("storage/")[1],
        )

    def connected_dbs(self):
        if os.path.exists("model/session/connected_dbs") and os.path.getsize(
                "model/session/connected_dbs") > 0:
            self.clear_tree()

            self.dbs = []

            with open("model/session/connected_dbs", "rb") as sessions:
                db_sessions = pickle.load(sessions)

            for db in db_sessions:
                connection = mysql.connect(
                    host=db["host"],
                    user=db["user"],
                    password=db["password"],
                    db=db["db"],
                    charset="utf8mb4",
                    cursorclass=mysql.cursors.DictCursor)

                temp_db = StandardItem(db["db"], 10, is_bold=True)

                self.dbs.append(db["db"])

                try:
                    with connection.cursor() as cursor:
                        cursor.execute("SHOW TABLES")
                        db_tables = cursor.fetchall()

                    for table in db_tables:
                        for key in table.keys():
                            temp_table = StandardItem(table[key], 9)
                            temp_db.appendRow(temp_table)
                finally:
                    connection.close()

                self.db_root.appendRow(temp_db)
        else:
            self.clear_tree()
            self.dbs = []
            no_db = StandardItem("No Connected Databases", 10, is_bold=True)
            self.db_root.appendRow(no_db)

    def table_clicked(self, val):
        self.is_db = False
        if os.path.exists("model/session/connected_dbs") and len(
                self.dbs) != 0:
            for db in self.dbs:
                if db == val.data():
                    self.is_db = True

                    remove_choice = QMessageBox.question(
                        self.db_tree, "Disconnect Database",
                        f'Do you want to remove "{val.data()}" from connected databases?',
                        QMessageBox.Yes | QMessageBox.No)

                    if remove_choice == QMessageBox.Yes:
                        with open("model/session/connected_dbs",
                                  "rb") as sessions:
                            db_sessions = pickle.load(sessions)

                        db_sessions[:] = [
                            db for db in db_sessions
                            if db.get('db') != val.data()
                        ]

                        for db in db_sessions:
                            if db["index"] != 1:
                                db["index"] -= 1

                        self.dbs[:] = [
                            db for db in self.dbs if db != val.data()
                        ]

                        if len(db_sessions) == 0:
                            os.remove("model/session/connected_dbs")
                        else:
                            with open("model/session/connected_dbs",
                                      "wb") as sessions:
                                pickle.dump(db_sessions, sessions)

                        QMessageBox.information(
                            self.db_tree, "(㇏(•̀ᵥᵥ•́)ノ)",
                            f'Database "{val.data()}" successfully disconnected.',
                            QMessageBox.Ok)
                        self.connected_dbs()
                        break

                    if remove_choice == QMessageBox.No:
                        break

            if not self.is_db:
                user_reply = QMessageBox.question(
                    self.db_tree, "Answer. Thanks.",
                    f'Do you want to open the "{val.data()}" table?',
                    QMessageBox.Open | QMessageBox.Cancel)

                if user_reply == QMessageBox.Cancel:
                    pass

                if user_reply == QMessageBox.Open:
                    workspace = DBWorkspace(val.parent().data(), val.data(),
                                            self.central_widget)
                    self.central_widget.add_tab(
                        workspace,
                        QIcon("view/images/menubar/database-connect.png"),
                        val.data(),
                    )

    def clear_tree(self):
        self.db_model.clear()
        self.db_model.setHorizontalHeaderLabels(["Database"])
        self.db_root = self.db_model.invisibleRootItem()
Beispiel #16
0
class FileBrowser(QObject):
    file_selected = Signal(str)
    file_activated = Signal(str)

    def __init__(self, app, window):
        QObject.__init__(self)
        self.app = app
        self.view = window.file_tree
        self.show_hidden_chk = window.show_hidden
        self.name_filter_combo = window.name_filter
        self.model = QFileSystemModel(self.view)
        self.icon_provider = FileIconProvider()
        if app.args.root:
            self.model.setRootPath(app.args.root)
            self.current_path = app.args.root
        else:
            self.model.setRootPath("")
            self.current_path = os.path.realpath(os.curdir)
        self.model.setIconProvider(self.icon_provider)
        self.view.setModel(self.model)
        self.view.sortByColumn(0, Qt.AscendingOrder)
        self.view.setSortingEnabled(True)
        index = self.model.index(self.current_path)
        if app.args.root:
            self.view.setRootIndex(index)
        self.view.setExpanded(index, True)
        self.view.setCurrentIndex(index)
        self.view.setDragDropMode(QAbstractItemView.DragDropMode.DragOnly)
        self.view.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.add_name_filters()
        self.apply_show_hidden()
        self.apply_name_filters()
        self.model.setNameFilterDisables(False)
        self.model.directoryLoaded.connect(self.directory_loaded)
        self.model.dataChanged.connect(self.data_changed)
        selection_model = self.view.selectionModel()
        selection_model.selectionChanged.connect(self.selection_changed)
        self.show_hidden_chk.stateChanged.connect(self.apply_show_hidden)
        self.name_filter_combo.currentIndexChanged.connect(
            self.apply_name_filters)
        self.view.doubleClicked.connect(self.double_clicked)

    def add_name_filters(self):
        for name, filters in NAME_FILTERS:
            label = "{} ({})".format(name, ", ".join(filters))
            self.name_filter_combo.addItem(label, filters)
        self.name_filter_combo.setCurrentIndex(0)

    @Slot()
    def apply_show_hidden(self):
        show = self.show_hidden_chk.checkState()
        logging.debug("apply_show_hidden(): %r", show)
        flags = QDir.AllDirs | QDir.Files | QDir.NoDotAndDotDot
        if show:
            flags |= QDir.Hidden
        self.model.setFilter(flags)
        QTimer.singleShot(100, self.scroll_to_current)

    @Slot()
    def apply_name_filters(self):
        filters = self.name_filter_combo.currentData()
        self.model.setNameFilters(filters)
        QTimer.singleShot(100, self.scroll_to_current)

    @Slot(str)
    def directory_loaded(self, path):
        logger.debug("directory loaded: %s", path)
        if path == self.current_path:
            logger.debug("requesting scrolling")
            QTimer.singleShot(100, self.scroll_to_current)

    @Slot()
    def data_changed(self, *args):
        logger.debug("Data changed: %r", args)

    @Slot()
    def scroll_to_current(self):
        index = self.model.index(self.current_path)
        self.view.scrollTo(index)
        self.view.resizeColumnToContents(0)

    @Slot(QItemSelection)
    def selection_changed(self, selection):
        indexes = selection.indexes()
        if indexes:
            index = indexes[0]
            path = self.model.filePath(index)
            if os.path.isfile(path):
                self.file_selected.emit(path)
            self.current_path = path

    @Slot(QModelIndex)
    def double_clicked(self, index):
        path = self.model.filePath(index)
        if os.path.isfile(path):
            self.file_activated.emit(path)
Beispiel #17
0
class TriageFilePicker(QWidget):
	def __init__(self, context):
		super(TriageFilePicker, self).__init__()
		self.context = context
		self.actionHandler = UIActionHandler()
		self.actionHandler.setupActionHandler(self)
		self.contextMenu = Menu()
		self.contextMenuManager = ContextMenuManager(self)

		layout = QVBoxLayout()
		layout.setContentsMargins(0, 0, 0, 0)

		self.model = QFileSystemModel()
		self.model.setRootPath("")
		self.model.setFilter(QDir.AllEntries | QDir.Hidden | QDir.System)
		self.tree = QTreeView(self)
		self.tree.setModel(self.model)
		self.tree.setSelectionMode(QAbstractItemView.ExtendedSelection)
		self.tree.setColumnWidth(0, 500)
		layout.addWidget(self.tree, 1)

		self.setLayout(layout)

		self.tree.doubleClicked.connect(self.onDoubleClick)

		recentFile = QSettings().value("triage/recentFile", os.path.expanduser("~"))
		while len(recentFile) > 0:
			f = self.model.index(recentFile)
			if f.isValid():
				self.tree.scrollTo(f)
				self.tree.setExpanded(f, True)
				break
			parentDir = os.path.dirname(recentFile)
			if parentDir == recentFile:
				break
			recentFile = parentDir

		self.actionHandler.bindAction("Open Selected Files", UIAction(
			lambda context: self.openSelectedFiles(),
			lambda context: self.areFilesSelected()))
		self.contextMenu.addAction("Open Selected Files", "Open")

	def contextMenuEvent(self, event):
		self.contextMenuManager.show(self.contextMenu, self.actionHandler)

	def onDoubleClick(self, index):
		self.openSelectedFiles()

	def openSelectedFiles(self):
		failedToOpen = []
		files = set()

		for index in self.tree.selectionModel().selectedIndexes():
			if self.model.fileInfo(index).isFile():
				files.add(self.model.fileInfo(index).absoluteFilePath())

		for filename in files:
				QSettings().setValue("triage/recentFile", filename)

				f = FileContext.openFilename(filename)
				if not f:
					failedToOpen.append(filename)
					continue

				f.createBinaryViews()
				for data in f.getAllDataViews():
					Settings().set_string("analysis.mode", Settings().get_string("triage.analysisMode"), data)
					Settings().set_bool("triage.preferSummaryView", True, data)
					if data.view_type != "Raw":
						linearSweepMode = Settings().get_string("triage.linearSweep")
						if linearSweepMode == "none":
							Settings().set_bool("analysis.linearSweep.autorun", False, data)
						elif linearSweepMode == "partial":
							Settings().set_bool("analysis.linearSweep.autorun", True, data)
							Settings().set_bool("analysis.linearSweep.controlFlowGraph", False, data)
						elif linearSweepMode == "full":
							Settings().set_bool("analysis.linearSweep.autorun", True, data)
							Settings().set_bool("analysis.linearSweep.controlFlowGraph", True, data)

				self.context.openFileContext(f)

		if len(failedToOpen) > 0:
			QMessageBox.critical(self, "Error", "Unable to open:\n" + "\n".join(failedToOpen))

	def areFilesSelected(self):
		return self.tree.selectionModel().hasSelection()
Beispiel #18
0
class FileSystemWidget(QWidget):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.currentRootPath = '/'
        self.currentPath = QDir.currentPath()

        self.mainWindow = parent

        self.chooseDirAction = QAction(IconFactory.getIcon('folder'),
                                       'Root directory',
                                       self,
                                       statusTip="Change root directory",
                                       triggered=self.chooseRootDir)
        self.showOFAction = QAction(IconFactory.getIcon('filter_alt'),
                                    'Show only FITS files',
                                    self,
                                    statusTip="Show only FITS/all files",
                                    triggered=self.showOFFiles)
        self.showOFAction.setCheckable(True)
        self.showOFAction.toggled.connect(self.showOFFiles)

        self.chooseDirBtn = QToolButton()
        self.chooseDirBtn.setDefaultAction(self.chooseDirAction)

        self.showOFBtn = QToolButton()
        self.showOFBtn.setDefaultAction(self.showOFAction)

        iconlayout = QHBoxLayout()
        iconlayout.setAlignment(Qt.AlignLeft)
        iconlayout.addWidget(self.chooseDirBtn)
        iconlayout.addWidget(self.showOFBtn)

        self.viewsSplitter = QSplitter(Qt.Horizontal)
        self.viewsSplitter.splitterMoved.connect(self.splitterMoved)

        self.dirsModel = QFileSystemModel(self)
        self.dirsModel.setOption(QFileSystemModel.DontWatchForChanges, True)
        self.dirsModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)
        self.dirsModel.setNameFilterDisables(False)

        self.dirs = QTreeView()
        self.dirs.setModel(self.dirsModel)
        self.dirs.hideColumn(1)
        self.dirs.hideColumn(2)
        self.dirs.hideColumn(3)

        self.dirs.clicked.connect(self.onDirsClick)
        self.dirs.doubleClicked.connect(self.onDirsDoubleClick)

        self.filesModel = QFileSystemModel(self)
        self.filesModel.setOption(QFileSystemModel.DontWatchForChanges, True)
        self.filesModel.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.filesModel.setNameFilterDisables(False)

        self.files = QListView()
        self.files.setModel(self.filesModel)
        self.files.doubleClicked.connect(self.onFilesDoubleClick)

        self.viewsSplitter.addWidget(self.dirs)
        self.viewsSplitter.addWidget(self.files)
        viewslayout = QHBoxLayout()
        viewslayout.addWidget(self.viewsSplitter)

        layout = QVBoxLayout()
        layout.addLayout(iconlayout)
        layout.addLayout(viewslayout)

        self.setLayout(layout)

        self.dirsModel.setRootPath(self.currentRootPath)
        self.dirs.setRootIndex(self.dirsModel.index(self.currentRootPath))

        index = self.dirsModel.index(self.currentPath)
        self.dirs.setCurrentIndex(index)
        self.dirs.setExpanded(index, True)

        self.filesModel.setRootPath(self.currentPath)
        self.files.setRootIndex(self.filesModel.index(self.currentPath))

    def splitterMoved(self, pos, index):
        if pos == 0:
            self.filesModel.setFilter(QDir.NoDot | QDir.AllEntries
                                      | QDir.DirsFirst | QDir.Type)
        elif pos == self.viewsSplitter.width(
        ) - self.viewsSplitter.handleWidth():
            self.dirsModel.setFilter(QDir.NoDotAndDotDot | QDir.AllEntries)
        else:
            self.dirsModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)
            self.filesModel.setFilter(QDir.NoDotAndDotDot | QDir.Files)

    def onDirsClick(self, item):
        index = self.dirs.selectedIndexes()[0]
        info = self.dirsModel.fileInfo(index)
        if info.isDir():
            self.currentPath = info.filePath()
            self.files.setRootIndex(
                self.filesModel.setRootPath(info.filePath()))

    def onDirsDoubleClick(self, item):
        index = self.dirs.selectedIndexes()[0]
        info = self.dirsModel.fileInfo(index)
        if info.isDir():
            self.currentPath = info.filePath()
            self.files.setRootIndex(
                self.filesModel.setRootPath(info.filePath()))
        else:
            self.mainWindow.open_fits(info.filePath())

    def onFilesDoubleClick(self, item):
        index = self.files.selectedIndexes()[0]
        info = self.filesModel.fileInfo(index)
        if info.isDir():
            self.setPath(info.filePath())
        else:
            try:
                self.mainWindow.open_fits(info.filePath())
            except FileNotFoundError:
                self.setPath(self.currentPath)  # refesh maybe?

    def setPath(self, path):
        self.currentPath = path

        index = self.dirsModel.index(self.currentPath)
        self.dirs.setCurrentIndex(index)
        self.dirs.setExpanded(index, True)

        self.files.setRootIndex(self.filesModel.setRootPath(self.currentPath))

    def chooseRootDir(self):
        dir = QFileDialog.getExistingDirectory(self, 'Select directory')
        if dir:
            self.setRootPath(dir)

    def setRootPath(self, dir):
        self.currentRootPath = dir

        self.dirsModel.setRootPath(self.currentRootPath)
        self.dirs.setRootIndex(self.dirsModel.index(self.currentRootPath))

        self.setPath(self.currentRootPath)

    def showOFFiles(self):
        if self.showOFAction.isChecked():
            self.dirsModel.setNameFilters(["*.FITS", "*.fits"])
            self.filesModel.setNameFilters(["*.FITS", "*.fits"])
        else:
            self.dirsModel.setNameFilters(["*"])
            self.filesModel.setNameFilters(["*"])

    def writeSettings(self, settings):
        settings.beginGroup("fileWidget")
        settings.setValue('splitterGeometry',
                          self.viewsSplitter.saveGeometry())
        settings.setValue('splitterState', self.viewsSplitter.saveState())
        settings.setValue('rootPath', self.currentRootPath)
        settings.setValue('path', self.currentPath)
        settings.endGroup()

    def readSettings(self, settings):
        settings.beginGroup("fileWidget")
        self.viewsSplitter.restoreGeometry(settings.value("splitterGeometry"))
        self.viewsSplitter.restoreState(settings.value("splitterState"))
        rootPath = settings.value("rootPath")
        path = settings.value("path")
        settings.endGroup()

        if rootPath is None:
            rootPath = '/'
        self.setRootPath(rootPath)

        if path is None:
            path = QDir.currentPath()
        self.setPath(path)

        self.splitterMoved(self.viewsSplitter.handle(1).pos().x(), 0)
Beispiel #19
0
class TestController(Window):
    """Contains code for  the window that the user initially sees"""
    def __init__(self):
        if not path.exists(algorithm_directory):
            os.makedirs(algorithm_directory, exist_ok=True)

        self.fmodel = QFileSystemModel()
        self.fmodel.setRootPath(algorithm_directory)
        self.module_list = QTreeView()
        self.module_list.setModel(self.fmodel)
        self.module_list.setRootIndex(self.fmodel.index(algorithm_directory))
        self.module_button = QPushButton("Change Directory")
        self.module_button.clicked.connect(self.change_dir)

        self.start_date = ToggleButton('Start Date')
        self.end_date = ToggleButton('End Date', 'Default (Present)')

        self.test_types = ['Profit', 'Accuracy']
        self.test_type = QComboBox()
        self.test_type.addItems(self.test_types)

        self.test_output = QTextEdit()
        self.test_output.setDisabled(True)
        self.run_btn = QPushButton('Run Test')

        self.profit = QLCDNumber()
        self.accuracy = QLCDNumber()

        super().__init__('Jencks Stock Algorithm Tester')

    def setup_left_column(self):
        self.left.addWidget(QLabel("Test Files"))
        self.left.addWidget(self.module_list)
        self.left.addWidget(self.module_button)

    def setup_center_column(self):
        hbox = QHBoxLayout()
        hbox.addLayout(self.start_date.box)
        hbox.addLayout(self.end_date.box)
        self.center.addLayout(hbox)
        self.center.addWidget(QLabel('Test Type'))
        self.center.addWidget(self.test_type)
        self.center.addWidget(QLabel('Test Run Output'))
        self.center.addWidget(self.test_output)
        self.center.addWidget(self.run_btn)

    def setup_right_column(self):
        self.right.addWidget(QLabel('Test Diagnostics'))
        self.right.addWidget(QLabel('Profit'))
        self.right.addWidget(self.profit)
        self.right.addWidget(QLabel('Accuracy'))
        self.right.addWidget(self.accuracy)

    def setup_menus(self):
        super().setup_menus()
        self.menu_entries += [(self.edit_menu, 'Preferences',
                               self.open_preferences, 'Ctrl+Alt+P')]

    @Slot()
    def open_preferences(self, checked):
        print('Opening preference menu.')

    @Slot()
    def change_dir(self, checked):
        dialog = QFileDialog()
        fdir = dialog.getExistingDirectory()
        self.fmodel.setRootPath(fdir)
        self.module_list.setRootIndex(self.fmodel.index(fdir))
Beispiel #20
0
import sys
from PySide2.QtWidgets import QApplication, QSplitter, QFileSystemModel, QTreeView, QListView
from PySide2.QtCore import QDir

if __name__ == '__main__':
    app = QApplication(sys.argv)
    splitter = QSplitter()
    model = QFileSystemModel()
    model.setRootPath("/")
    tree = QTreeView(splitter)
    tree.setModel(model)
    tree.setRootIndex(model.index("/"))
    list = QListView(splitter)
    list.setModel(model)
    list.setRootIndex(model.index("/"))
    splitter.setWindowTitle(
        "A model with two views or two views with one model")
    splitter.show()
    app.exec_()
Beispiel #21
0
class Snippets(QDialog):

    def __init__(self, context, parent=None):
        super(Snippets, self).__init__(parent)
        # Create widgets
        self.setWindowModality(Qt.ApplicationModal)
        self.title = QLabel(self.tr("Snippet Editor"))
        self.saveButton = QPushButton(self.tr("&Save"))
        self.saveButton.setShortcut(QKeySequence(self.tr("Ctrl+S")))
        self.runButton = QPushButton(self.tr("&Run"))
        self.runButton.setShortcut(QKeySequence(self.tr("Ctrl+R")))
        self.closeButton = QPushButton(self.tr("Close"))
        self.clearHotkeyButton = QPushButton(self.tr("Clear Hotkey"))
        self.setWindowTitle(self.title.text())
        #self.newFolderButton = QPushButton("New Folder")
        self.browseButton = QPushButton("Browse Snippets")
        self.browseButton.setIcon(QIcon.fromTheme("edit-undo"))
        self.deleteSnippetButton = QPushButton("Delete")
        self.newSnippetButton = QPushButton("New Snippet")
        self.edit = QCodeEditor(HIGHLIGHT_CURRENT_LINE=False, SyntaxHighlighter=PythonHighlighter)
        self.edit.setPlaceholderText("python code")
        self.resetting = False
        self.columns = 3
        self.context = context

        self.keySequenceEdit = QKeySequenceEdit(self)
        self.currentHotkey = QKeySequence()
        self.currentHotkeyLabel = QLabel("")
        self.currentFileLabel = QLabel()
        self.currentFile = ""
        self.snippetDescription = QLineEdit()
        self.snippetDescription.setPlaceholderText("optional description")

        #Set Editbox Size
        font = getMonospaceFont(self)
        self.edit.setFont(font)
        font = QFontMetrics(font)
        self.edit.setTabStopWidth(4 * font.width(' ')); #TODO, replace with settings API

        #Files
        self.files = QFileSystemModel()
        self.files.setRootPath(snippetPath)
        self.files.setNameFilters(["*.py"])

        #Tree
        self.tree = QTreeView()
        self.tree.setModel(self.files)
        self.tree.setSortingEnabled(True)
        self.tree.hideColumn(2)
        self.tree.sortByColumn(0, Qt.AscendingOrder)
        self.tree.setRootIndex(self.files.index(snippetPath))
        for x in range(self.columns):
            #self.tree.resizeColumnToContents(x)
            self.tree.header().setSectionResizeMode(x, QHeaderView.ResizeToContents)
        treeLayout = QVBoxLayout()
        treeLayout.addWidget(self.tree)
        treeButtons = QHBoxLayout()
        #treeButtons.addWidget(self.newFolderButton)
        treeButtons.addWidget(self.browseButton)
        treeButtons.addWidget(self.newSnippetButton)
        treeButtons.addWidget(self.deleteSnippetButton)
        treeLayout.addLayout(treeButtons)
        treeWidget = QWidget()
        treeWidget.setLayout(treeLayout)

        # Create layout and add widgets
        buttons = QHBoxLayout()
        buttons.addWidget(self.clearHotkeyButton)
        buttons.addWidget(self.keySequenceEdit)
        buttons.addWidget(self.currentHotkeyLabel)
        buttons.addWidget(self.closeButton)
        buttons.addWidget(self.runButton)
        buttons.addWidget(self.saveButton)

        description = QHBoxLayout()
        description.addWidget(QLabel(self.tr("Description: ")))
        description.addWidget(self.snippetDescription)

        vlayoutWidget = QWidget()
        vlayout = QVBoxLayout()
        vlayout.addLayout(description)
        vlayout.addWidget(self.edit)
        vlayout.addLayout(buttons)
        vlayoutWidget.setLayout(vlayout)

        hsplitter = QSplitter()
        hsplitter.addWidget(treeWidget)
        hsplitter.addWidget(vlayoutWidget)

        hlayout = QHBoxLayout()
        hlayout.addWidget(hsplitter)

        self.showNormal() #Fixes bug that maximized windows are "stuck"
        #Because you can't trust QT to do the right thing here
        if (sys.platform == "darwin"):
            self.settings = QSettings("Vector35", "Snippet Editor")
        else:
            self.settings = QSettings("Vector 35", "Snippet Editor")
        if self.settings.contains("ui/snippeteditor/geometry"):
            self.restoreGeometry(self.settings.value("ui/snippeteditor/geometry"))
        else:
            self.edit.setMinimumWidth(80 * font.averageCharWidth())
            self.edit.setMinimumHeight(30 * font.lineSpacing())

        # Set dialog layout
        self.setLayout(hlayout)

        # Add signals
        self.saveButton.clicked.connect(self.save)
        self.closeButton.clicked.connect(self.close)
        self.runButton.clicked.connect(self.run)
        self.clearHotkeyButton.clicked.connect(self.clearHotkey)
        self.tree.selectionModel().selectionChanged.connect(self.selectFile)
        self.newSnippetButton.clicked.connect(self.newFileDialog)
        self.deleteSnippetButton.clicked.connect(self.deleteSnippet)
        #self.newFolderButton.clicked.connect(self.newFolder)
        self.browseButton.clicked.connect(self.browseSnippets)

        if self.settings.contains("ui/snippeteditor/selected"):
            selectedName = self.settings.value("ui/snippeteditor/selected")
            self.tree.selectionModel().select(self.files.index(selectedName), QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
            if self.tree.selectionModel().hasSelection():
                self.selectFile(self.tree.selectionModel().selection(), None)
                self.edit.setFocus()
                cursor = self.edit.textCursor()
                cursor.setPosition(self.edit.document().characterCount()-1)
                self.edit.setTextCursor(cursor)
            else:
                self.readOnly(True)
        else:
            self.readOnly(True)


    @staticmethod
    def registerAllSnippets():
        for action in list(filter(lambda x: x.startswith("Snippets\\"), UIAction.getAllRegisteredActions())):
            if action == "Snippets\\Snippet Editor...":
                continue
            UIActionHandler.globalActions().unbindAction(action)
            Menu.mainMenu("Tools").removeAction(action)
            UIAction.unregisterAction(action)

        for snippet in includeWalk(snippetPath, ".py"):
            snippetKeys = None
            (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(snippet)
            actionText = actionFromSnippet(snippet, snippetDescription)
            if snippetCode:
                if snippetKeys == None:
                    UIAction.registerAction(actionText)
                else:
                    UIAction.registerAction(actionText, snippetKeys)
                UIActionHandler.globalActions().bindAction(actionText, UIAction(makeSnippetFunction(snippetCode)))
                Menu.mainMenu("Tools").addAction(actionText, "Snippets")

    def clearSelection(self):
        self.keySequenceEdit.clear()
        self.currentHotkey = QKeySequence()
        self.currentHotkeyLabel.setText("")
        self.currentFileLabel.setText("")
        self.snippetDescription.setText("")
        self.edit.clear()
        self.tree.clearSelection()
        self.currentFile = ""

    def reject(self):
        self.settings.setValue("ui/snippeteditor/geometry", self.saveGeometry())

        if self.snippetChanged():
            question = QMessageBox.question(self, self.tr("Discard"), self.tr("You have unsaved changes, quit anyway?"))
            if question != QMessageBox.StandardButton.Yes:
                return
        self.accept()

    def browseSnippets(self):
        url = QUrl.fromLocalFile(snippetPath)
        QDesktopServices.openUrl(url);

    def newFolder(self):
        (folderName, ok) = QInputDialog.getText(self, self.tr("Folder Name"), self.tr("Folder Name: "))
        if ok and folderName:
            index = self.tree.selectionModel().currentIndex()
            selection = self.files.filePath(index)
            if QFileInfo(selection).isDir():
                QDir(selection).mkdir(folderName)
            else:
                QDir(snippetPath).mkdir(folderName)

    def selectFile(self, new, old):
        if (self.resetting):
            self.resetting = False
            return
        if len(new.indexes()) == 0:
            self.clearSelection()
            self.currentFile = ""
            self.readOnly(True)
            return
        newSelection = self.files.filePath(new.indexes()[0])
        self.settings.setValue("ui/snippeteditor/selected", newSelection)
        if QFileInfo(newSelection).isDir():
            self.readOnly(True)
            self.clearSelection()
            self.currentFile = ""
            return

        if old and old.length() > 0:
            oldSelection = self.files.filePath(old.indexes()[0])
            if not QFileInfo(oldSelection).isDir() and self.snippetChanged():
                question = QMessageBox.question(self, self.tr("Discard"), self.tr("Snippet changed. Discard changes?"))
                if question != QMessageBox.StandardButton.Yes:
                    self.resetting = True
                    self.tree.selectionModel().select(old, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
                    return False

        self.currentFile = newSelection
        self.loadSnippet()

    def loadSnippet(self):
        self.currentFileLabel.setText(QFileInfo(self.currentFile).baseName())
        (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(self.currentFile)
        self.snippetDescription.setText(snippetDescription) if snippetDescription else self.snippetDescription.setText("")
        self.keySequenceEdit.setKeySequence(snippetKeys) if snippetKeys else self.keySequenceEdit.setKeySequence(QKeySequence(""))
        self.edit.setPlainText(snippetCode) if snippetCode else self.edit.setPlainText("")
        self.readOnly(False)

    def newFileDialog(self):
        (snippetName, ok) = QInputDialog.getText(self, self.tr("Snippet Name"), self.tr("Snippet Name: "))
        if ok and snippetName:
            if not snippetName.endswith(".py"):
                snippetName += ".py"
            index = self.tree.selectionModel().currentIndex()
            selection = self.files.filePath(index)
            if QFileInfo(selection).isDir():
                path = os.path.join(selection, snippetName)
            else:
                path = os.path.join(snippetPath, snippetName)
                self.readOnly(False)
            open(path, "w").close()
            self.tree.setCurrentIndex(self.files.index(path))
            log_debug("Snippet %s created." % snippetName)

    def readOnly(self, flag):
        self.keySequenceEdit.setEnabled(not flag)
        self.snippetDescription.setReadOnly(flag)
        self.edit.setReadOnly(flag)
        if flag:
            self.snippetDescription.setDisabled(True)
            self.edit.setDisabled(True)
        else:
            self.snippetDescription.setEnabled(True)
            self.edit.setEnabled(True)

    def deleteSnippet(self):
        selection = self.tree.selectedIndexes()[::self.columns][0] #treeview returns each selected element in the row
        snippetName = self.files.fileName(selection)
        question = QMessageBox.question(self, self.tr("Confirm"), self.tr("Confirm deletion: ") + snippetName)
        if (question == QMessageBox.StandardButton.Yes):
            log_debug("Deleting snippet %s." % snippetName)
            self.clearSelection()
            self.files.remove(selection)
            self.registerAllSnippets()

    def snippetChanged(self):
        if (self.currentFile == "" or QFileInfo(self.currentFile).isDir()):
            return False
        (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(self.currentFile)
        if snippetKeys == None and not self.keySequenceEdit.keySequence().isEmpty():
            return True
        if snippetKeys != None and snippetKeys != self.keySequenceEdit.keySequence().toString():
            return True
        return self.edit.toPlainText() != snippetCode or \
               self.snippetDescription.text() != snippetDescription

    def save(self):
        log_debug("Saving snippet %s" % self.currentFile)
        outputSnippet = codecs.open(self.currentFile, "w", "utf-8")
        outputSnippet.write("#" + self.snippetDescription.text() + "\n")
        outputSnippet.write("#" + self.keySequenceEdit.keySequence().toString() + "\n")
        outputSnippet.write(self.edit.toPlainText())
        outputSnippet.close()
        self.registerAllSnippets()

    def run(self):
        if self.context == None:
            log_warn("Cannot run snippets outside of the UI at this time.")
            return
        if self.snippetChanged():
            question = QMessageBox.question(self, self.tr("Confirm"), self.tr("You have unsaved changes, must save first. Save?"))
            if (question == QMessageBox.StandardButton.No):
                return
            else:
                self.save()
        actionText = actionFromSnippet(self.currentFile, self.snippetDescription.text())
        UIActionHandler.globalActions().executeAction(actionText, self.context)

        log_debug("Saving snippet %s" % self.currentFile)
        outputSnippet = codecs.open(self.currentFile, "w", "utf-8")
        outputSnippet.write("#" + self.snippetDescription.text() + "\n")
        outputSnippet.write("#" + self.keySequenceEdit.keySequence().toString() + "\n")
        outputSnippet.write(self.edit.toPlainText())
        outputSnippet.close()
        self.registerAllSnippets()

    def clearHotkey(self):
        self.keySequenceEdit.clear()
Beispiel #22
0
class Snippets(QDialog):

    def __init__(self, parent=None):
        super(Snippets, self).__init__(parent)
        # Create widgets
        self.setWindowModality(Qt.NonModal)
        self.title = QLabel(self.tr("Snippet Editor"))
        self.saveButton = QPushButton(self.tr("Save"))
        self.revertButton = QPushButton(self.tr("Revert"))
        self.clearHotkeyButton = QPushButton(self.tr("Clear Hotkey"))
        self.setWindowTitle(self.title.text())
        self.newFolderButton = QPushButton("New Folder")
        self.deleteSnippetButton = QPushButton("Delete")
        self.newSnippetButton = QPushButton("New Snippet")
        self.edit = QPlainTextEdit()
        self.resetting = False
        self.columns = 3

        self.keySequenceEdit = QKeySequenceEdit(self)
        self.currentHotkey = QKeySequence()
        self.currentHotkeyLabel = QLabel("")
        self.currentFileLabel = QLabel()
        self.currentFile = ""
        self.snippetDescription = QLineEdit()
        self.snippetEditsPending = False

        self.clearSelection()

        #Set Editbox Size
        font = getMonospaceFont(self)
        self.edit.setFont(font)
        font = QFontMetrics(font)
        self.edit.setTabStopWidth(4 * font.width(' ')); #TODO, replace with settings API

        #Files
        self.files = QFileSystemModel()
        self.files.setRootPath(snippetPath)
        self.files.setNameFilters(["*.py"])

        #Tree
        self.tree = QTreeView()
        self.tree.setModel(self.files)
        self.tree.setSortingEnabled(True)
        self.tree.hideColumn(2)
        self.tree.sortByColumn(0, Qt.AscendingOrder)
        self.tree.setRootIndex(self.files.index(snippetPath))
        for x in range(self.columns):
            #self.tree.resizeColumnToContents(x)
            self.tree.header().setSectionResizeMode(x, QHeaderView.ResizeToContents) 
        treeLayout = QVBoxLayout()
        treeLayout.addWidget(self.tree)
        treeButtons = QHBoxLayout()
        treeButtons.addWidget(self.newFolderButton)
        treeButtons.addWidget(self.newSnippetButton)
        treeButtons.addWidget(self.deleteSnippetButton)
        treeLayout.addLayout(treeButtons)
        treeWidget = QWidget()
        treeWidget.setLayout(treeLayout)

        # Create layout and add widgets
        buttons = QHBoxLayout()
        buttons.addWidget(self.clearHotkeyButton)
        buttons.addWidget(self.keySequenceEdit)
        buttons.addWidget(self.currentHotkeyLabel)
        buttons.addWidget(self.revertButton)
        buttons.addWidget(self.saveButton)

        description = QHBoxLayout()
        description.addWidget(QLabel(self.tr("Description: ")))
        description.addWidget(self.snippetDescription)

        vlayoutWidget = QWidget()
        vlayout = QVBoxLayout()
        vlayout.addWidget(self.currentFileLabel)
        vlayout.addWidget(self.edit)
        vlayout.addLayout(description)
        vlayout.addLayout(buttons)
        vlayoutWidget.setLayout(vlayout)

        hsplitter = QSplitter()
        hsplitter.addWidget(treeWidget)
        hsplitter.addWidget(vlayoutWidget)

        hlayout = QHBoxLayout()
        hlayout.addWidget(hsplitter)

        self.showNormal() #Fixes bug that maximized windows are "stuck"
        self.settings = QSettings("Vector 35", "Snippet Editor")
        if self.settings.contains("ui/snippeteditor/geometry"):
            self.restoreGeometry(self.settings.value("ui/snippeteditor/geometry"))
        else:
            self.edit.setMinimumWidth(80 * font.averageCharWidth())
            self.edit.setMinimumHeight(30 * font.lineSpacing())

        # Set dialog layout
        self.setLayout(hlayout)

        # Add signals
        self.saveButton.clicked.connect(self.save)
        self.revertButton.clicked.connect(self.loadSnippet)
        self.clearHotkeyButton.clicked.connect(self.clearHotkey)
        self.tree.selectionModel().selectionChanged.connect(self.selectFile)
        self.newSnippetButton.clicked.connect(self.newFileDialog)
        self.deleteSnippetButton.clicked.connect(self.deleteSnippet)
        self.newFolderButton.clicked.connect(self.newFolder)

    def registerAllSnippets(self):
        for action in list(filter(lambda x: x.startswith("Snippet\\"), UIAction.getAllRegisteredActions())):
            UIActionHandler.globalActions().unbindAction(action)
            UIAction.unregisterAction(action)

        for snippet in includeWalk(snippetPath, ".py"):
            (snippetDescription, snippetKey, snippetCode) = loadSnippetFromFile(snippet)
            if not snippetDescription:
                actionText = "Snippet\\" + snippet
            else:
                actionText = "Snippet\\" + snippetDescription
            UIAction.registerAction(actionText, snippetKey)
            UIActionHandler.globalActions().bindAction(actionText, UIAction(makeSnippetFunction(snippetCode)))

    def clearSelection(self):
        self.keySequenceEdit.clear()
        self.currentHotkey = QKeySequence()
        self.currentHotkeyLabel.setText("")
        self.currentFileLabel.setText("")
        self.snippetDescription.setText("")
        self.edit.setPlainText("")

    def reject(self):
        self.settings.setValue("ui/snippeteditor/geometry", self.saveGeometry())

        if self.snippetChanged():
            question = QMessageBox.question(self, self.tr("Discard"), self.tr("You have unsaved changes, quit anyway?"))
            if question != QMessageBox.StandardButton.Yes:
                return
        self.accept()

    def newFolder(self):
        (folderName, ok) = QInputDialog.getText(self, self.tr("Folder Name"), self.tr("Folder Name: "))
        if ok and folderName:
            index = self.tree.selectionModel().currentIndex()
            selection = self.files.filePath(index)
            if QFileInfo(selection).isDir():
                QDir(selection).mkdir(folderName)
            else:
                QDir(snippetPath).mkdir(folderName)    

    def selectFile(self, new, old):
        if (self.resetting):
            self.resetting = False
            return
        newSelection = self.files.filePath(new.indexes()[0])
        if QFileInfo(newSelection).isDir():
            self.clearSelection()
            return

        if old.length() > 0:
            oldSelection = self.files.filePath(old.indexes()[0])
            if not QFileInfo(oldSelection).isDir() and self.snippetChanged():
                question = QMessageBox.question(self, self.tr("Discard"), self.tr("Snippet changed. Discard changes?"))
                if question != QMessageBox.StandardButton.Yes:
                    self.resetting = True
                    self.tree.selectionModel().select(old, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
                    return False

        self.currentFile = newSelection
        self.loadSnippet()

    def loadSnippet(self):
        self.currentFileLabel.setText(QFileInfo(self.currentFile).baseName())
        log_debug("Loading %s as a snippet." % self.currentFile)
        (snippetDescription, snippetKey, snippetCode) = loadSnippetFromFile(self.currentFile)
        self.snippetDescription.setText(snippetDescription) if snippetDescription else self.snippetDescription.setText("")
        self.keySequenceEdit.setKeySequence(snippetKey[0]) if len(snippetKey) != 0 else self.keySequenceEdit.setKeySequence(QKeySequence(""))
        self.edit.setPlainText(snippetCode) if snippetCode else self.edit.setPlainText("")

    def newFileDialog(self):
        (snippetName, ok) = QInputDialog.getText(self, self.tr("Snippet Name"), self.tr("Snippet Name: "))
        if ok and snippetName:
            if not snippetName.endswith(".py"):
                snippetName += ".py"
            index = self.tree.selectionModel().currentIndex()
            selection = self.files.filePath(index)
            if QFileInfo(selection).isDir():
                open(os.path.join(selection, snippetName), "w").close()
            else:
                open(os.path.join(snippetPath, snippetName), "w").close()
            log_debug("Snippet %s created." % snippetName)

    def deleteSnippet(self):
        selection = self.tree.selectedIndexes()[::self.columns][0] #treeview returns each selected element in the row
        snippetName = self.files.fileName(selection)
        question = QMessageBox.question(self, self.tr("Confirm"), self.tr("Confirm deletion: ") + snippetName)
        if (question == QMessageBox.StandardButton.Yes):
            log_debug("Deleting snippet %s." % snippetName)
            self.clearSelection()
            self.files.remove(selection)

    def snippetChanged(self):
        if (self.currentFile == "" or QFileInfo(self.currentFile).isDir()):
            return False
        (snippetDescription, snippetKey, snippetCode) = loadSnippetFromFile(self.currentFile)
        if (not snippetCode):
            return False
        if len(snippetKey) == 0 and not self.keySequenceEdit.keySequence().isEmpty():
            return True
        if len(snippetKey) != 0 and snippetKey[0] != self.keySequenceEdit.keySequence():
            return True
        return self.edit.toPlainText() != snippetCode or \
               self.snippetDescription.text() != snippetDescription

    def save(self):
        log_debug("Saving snippet %s" % self.currentFile)
        outputSnippet = open(self.currentFile, "w")
        outputSnippet.write("#" + self.snippetDescription.text() + "\n")
        outputSnippet.write("#" + self.keySequenceEdit.keySequence().toString() + "\n")
        outputSnippet.write(self.edit.toPlainText())
        outputSnippet.close()
        self.registerAllSnippets()

    def clearHotkey(self):
        self.keySequenceEdit.clear()
Beispiel #23
0
class SVDBrowser(QDialog):
    def __init__(self, context, parent=None):
        super(SVDBrowser, self).__init__(parent)
        QWebEngineProfile.defaultProfile().downloadRequested.connect(
            self.on_downloadRequested)

        # Create widgets
        #self.setWindowModality(Qt.ApplicationModal)
        self.title = QLabel(self.tr("SVD Browser"))
        self.closeButton = QPushButton(self.tr("Close"))
        self.setWindowTitle(self.title.text())
        self.browseButton = QPushButton("Browse SVD Folder")
        self.deleteSvdButton = QPushButton("Delete")
        self.applySvdButton = QPushButton("Apply SVD")
        self.view = QWebEngineView()
        url = "https://developer.arm.com/tools-and-software/embedded/cmsis/cmsis-search"
        self.view.load(QUrl(url))
        self.columns = 3
        self.context = context

        self.currentFileLabel = QLabel()
        self.currentFile = ""

        #Files
        self.files = QFileSystemModel()
        self.files.setRootPath(svdPath)
        self.files.setNameFilters(["*.svd", "*.patched"])

        #Tree
        self.tree = QTreeView()
        self.tree.setModel(self.files)
        self.tree.setSortingEnabled(True)
        self.tree.hideColumn(2)
        self.tree.sortByColumn(0, Qt.AscendingOrder)
        self.tree.setRootIndex(self.files.index(svdPath))
        for x in range(self.columns):
            #self.tree.resizeColumnToContents(x)
            self.tree.header().setSectionResizeMode(
                x, QHeaderView.ResizeToContents)
        treeLayout = QVBoxLayout()
        treeLayout.addWidget(self.tree)
        treeButtons = QHBoxLayout()
        #treeButtons.addWidget(self.newFolderButton)
        treeButtons.addWidget(self.browseButton)
        treeButtons.addWidget(self.applySvdButton)
        treeButtons.addWidget(self.deleteSvdButton)
        treeLayout.addLayout(treeButtons)
        treeWidget = QWidget()
        treeWidget.setLayout(treeLayout)

        # Create layout and add widgets
        buttons = QHBoxLayout()
        buttons.addWidget(self.closeButton)

        vlayoutWidget = QWidget()
        vlayout = QVBoxLayout()
        vlayout.addWidget(self.view)
        vlayout.addLayout(buttons)
        vlayoutWidget.setLayout(vlayout)

        hsplitter = QSplitter()
        hsplitter.addWidget(treeWidget)
        hsplitter.addWidget(vlayoutWidget)

        hlayout = QHBoxLayout()
        hlayout.addWidget(hsplitter)

        self.showMaximized()  #Fixes bug that maximized windows are "stuck"
        #Because you can't trust QT to do the right thing here

        # Set dialog layout
        self.setLayout(hlayout)

        # Add signals
        self.closeButton.clicked.connect(self.close)
        self.tree.selectionModel().selectionChanged.connect(self.selectFile)
        self.applySvdButton.clicked.connect(self.applySvd)
        self.deleteSvdButton.clicked.connect(self.deleteSvd)
        self.browseButton.clicked.connect(self.browseSvd)

    def browseSvd(self):
        url = QUrl.fromLocalFile(svdPath)
        QDesktopServices.openUrl(url)

    def selectFile(self, new, old):
        if len(new.indexes()) == 0:
            self.tree.clearSelection()
            self.currentFile = ""
            return
        newSelection = self.files.filePath(new.indexes()[0])
        if QFileInfo(newSelection).isDir():
            self.tree.clearSelection()
            self.currentFile = ""
            return
        self.currentFile = newSelection

    def applySvd(self):
        selection = self.tree.selectedIndexes()[::self.columns][
            0]  #treeview returns each selected element in the row
        svdName = self.files.fileName(selection)
        if (svdName != ""):
            question = QMessageBox.question(
                self, self.tr("Confirm"),
                self.
                tr(f"Confirm applying {svdName} to {os.path.basename(self.context.file.filename)} : "
                   ))
            if (question == QMessageBox.StandardButton.Yes):
                log_debug("SVD Browser: Applying SVD %s." % svdName)
                load_svd(self.context, self.currentFile)
                self.close()

    def deleteSvd(self):
        selection = self.tree.selectedIndexes()[::self.columns][
            0]  #treeview returns each selected element in the row
        svdName = self.files.fileName(selection)
        question = QMessageBox.question(
            self, self.tr("Confirm"),
            self.tr("Confirm deletion: ") + svdName)
        if (question == QMessageBox.StandardButton.Yes):
            log_debug("SVD Browser: Deleting SVD %s." % svdName)
            self.files.remove(selection)
            self.tree.clearSelection()

    def on_downloadRequested(self, download):
        old_path = download.url().path()  # download.path()
        suffix = QFileInfo(old_path).suffix()
        if (suffix.lower() in ["zip", "svd", "pack", "patched"]):
            log_debug(f"SVD Browser: Downloading {str(download.url())}")
            if suffix.lower() == "svd" or suffix.lower() == "patched":
                download.setDownloadDirectory(svdPath)
                download.accept()
            else:
                with TemporaryDirectory() as tempfolder:
                    log_debug(
                        f"SVD Browser: Downloading pack/zip to {tempfolder}")
                    fname = download.url().fileName()
                    r = requests.get(download.url().toString(),
                                     allow_redirects=True)
                    dlfile = os.path.join(tempfolder, fname)
                    open(dlfile, "wb").write(r.content)
                    '''
                    # TODO: See if the original QT Downloader can be fixed since it would
                    # help with situations where the user entered credentials in the browser.
                    download.setDownloadDirectory(tempfolder)
                    download.accept()
                    while not download.finished:
                        import time
                        time.sleep(100)
                    '''
                    if fname.endswith(".zip") or fname.endswith(".pack"):
                        destFolder = os.path.join(svdPath,
                                                  os.path.splitext(fname)[0])
                        log_debug(f"SVD Browser: Creating {destFolder}")
                        if not os.path.exists(destFolder):
                            os.mkdir(destFolder)
                        with ZipFile(dlfile, 'r') as zipp:
                            for ifname in zipp.namelist():
                                if ifname.endswith(".svd"):
                                    info = zipp.getinfo(ifname)
                                    info.filename = os.path.basename(
                                        info.filename)
                                    log_debug(
                                        f"SVD Browser: Extracting {info.filename} from {ifname}"
                                    )
                                    zipp.extract(info, path=destFolder)
                    else:
                        #Move file into place
                        shutil.move(dlfile, svdPath)
        else:
            show_message_box(
                "Invalid file",
                "That download does not appear to be a valid SVD/ZIP/PACK file."
            )
        download.cancel()