Exemple #1
0
class DockFolders(QDockWidget, Ui_dock_folders):

    def __init__(self, parent):
        QDockWidget.__init__(self, parent=parent)
        self.setupUi(self)
        self.mw = parent
        #
        self.ed_path.setText(self.mw.cfg.value("root_path", defaultValue=QDir.homePath()))
        self.setupDirModel()
        self.tree.clicked.connect(self.onDirClicked)
        # self.btn_selectdir.clicked.connect(self.onButtonSelectDir)
        self.ed_path.returnPressed.connect(self.setupDirModel)

    def setupDirModel(self):
        """ Show folders on tree view """
        path = self.ed_path.text()
        self.dirModel = QFileSystemModel()
        self.dirModel.setRootPath(path)
        self.dirModel.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot)
        self.tree.setModel(self.dirModel)
        self.tree.setRootIndex(self.dirModel.index(path))
        self.tree.hideColumn(1)
        self.tree.hideColumn(2)
        self.tree.hideColumn(3)
        self.tree.resizeColumnToContents(0)

    def onDirClicked(self, index):
        path = self.dirModel.fileInfo(index).absoluteFilePath()
        self.mw.loadAlbum(path)
Exemple #2
0
class FolderContents(QWidget):
    def __init__(self, editor):
        super().__init__(editor)
        self.editor = editor
        self.layout = QHBoxLayout()
        self.setLayout(self.layout)
        self.tView = QTreeView()
        self.createFileExplorer()

    def createFileExplorer(self):
        self.dirModel = QFileSystemModel()
        # self.fileModel = QFileSystemModel()
        # self.fmDialog = QDialog()

        # self.dirModel.setFilter()
        self.root = self.dirModel.setRootPath(QDir.homePath())
        self.dirModel.setFilter(QDir.NoDot | QDir.AllEntries)
        # self.dirModel.setFilter(QDir.AllDirs)
        self.tView.setModel(self.dirModel)
        self.layout.addWidget(self.tView)
        self.tView.setRootIndex(self.root)
        self.tView.doubleClicked.connect(self.clickAction)
        self.subdirs = 0
        self.current_dir = QDir.homePath()

    def clickAction(self, index):
        if index.data() == '..':
            if self.subdirs > 0:
                self.current_dir = self.current_dir.rsplit('/', 1)[0]
                self.tView.setRootIndex(
                    self.dirModel.setRootPath(self.current_dir))
                self.subdirs -= 1
            # print(QDir(index.parent()).absoluteFilePath())
            # self.dirModel.setRootPath(QDir(index.parent()).absolutePath())
        elif self.dirModel.fileInfo(index).isDir():
            self.subdirs += 1
            self.current_dir = self.current_dir + '/' + str(index.data())
            self.tView.setRootIndex(index)
        elif self.dirModel.fileInfo(index).isFile():
            extension = index.data().rsplit('.', 1)[1]
            if extension == 'nc' or extension == 'nc4':
                subprocess.call('ncview ' + self.current_dir + '/' +
                                index.data(),
                                shell=True)
            elif extension == 'ncl':
                self.editor.AddTab(self.current_dir + '/' + index.data())
Exemple #3
0
class AssetBrowser(QMainWindow, Ui_MainWindow):
    asset_clicked = pyqtSignal(str, str, name='assetClicked')

    def __init__(self):
        super(AssetBrowser, self).__init__()
        self.setupUi(self)

        self.dir_model = QFileSystemModel()
        self.dir_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)
        self.dir_model.setReadOnly(False)

        self.dir_view.setModel(self.dir_model)
        self.dir_view.hideColumn(1)
        self.dir_view.hideColumn(2)
        self.dir_view.hideColumn(3)

        self.file_model = QFileSystemModel()
        self.file_model.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.file_model.setReadOnly(False)

        self.file_view.setModel(self.file_model)

    def open_project(self, project_dir):
        path = os.path.join(project_dir)

        self.dir_model.setRootPath(path)
        self.file_model.setRootPath(path)

        self.dir_view.setRootIndex(self.dir_model.index(path))
        self.file_view.setRootIndex(self.file_model.index(path))

    def dir_clicked(self, idx):
        path = self.dir_model.fileInfo(idx).absoluteFilePath()

        self.file_view.setRootIndex(self.file_model.setRootPath(path))

    def file_doubleclicked(self, idx):
        fileinfo = self.file_model.fileInfo(idx)

        path = fileinfo.absoluteFilePath()
        ext = fileinfo.suffix()

        self.asset_clicked.emit(path, ext)
Exemple #4
0
class DirectoryTree(QWidget):
    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 file system view'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.rootPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot)
        self.tree = QTreeView()
        self.tree.setModel(self.model)
        self.tree.hideColumn(1)
        self.tree.hideColumn(2)
        self.tree.hideColumn(3)

        self.tree.setAnimated(False)
        self.tree.setIndentation(20)
        self.tree.setSortingEnabled(True)

        self.tree.setWindowTitle("Dir View")
        self.tree.resize(640, 480)

        self.fileModel = QFileSystemModel()
        self.fileModel.setRootPath(QDir.rootPath())
        self.list = QTableView()
        self.list.setModel(self.fileModel)
        self.list.setShowGrid(False)
        self.list.verticalHeader().setVisible(False)
        self.list.setSelectionBehavior(QTableView().SelectRows)

        self.tree.clicked.connect(self.onClicked)

        windowLayout = QHBoxLayout()
        windowLayout.addWidget(self.tree)
        windowLayout.addWidget(self.list)
        self.setLayout(windowLayout)

        self.show()

    def onClicked(self, index):
        path = self.model.fileInfo(index).absoluteFilePath()
        self.list.setRootIndex(self.fileModel.setRootPath(path))
Exemple #5
0
class MainWindow(QMainWindow):
    def __init__(self, parent=None):

        super(MainWindow, self).__init__(parent)

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

        path = QDir.currentPath()

        self.browser_model = QFileSystemModel()
        self.browser_model.setRootPath(path)
        self.browser_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)

        self.ui.browser.setModel(self.browser_model)

        self.details_model = QFileSystemModel()
        self.details_model.setRootPath(path)
        self.details_model.setFilter(QDir.NoDotAndDotDot | QDir.AllEntries)

        self.ui.details.setModel(self.details_model)

        column_count = self.browser_model.columnCount()
        for i in range(1, column_count):
            self.ui.browser.hideColumn(i)

        self.setupUi()

    def setupUi(self):
        self.ui.browser.clicked.connect(self.browser_clicked)

    def browser_clicked(self, index):

        file_info = self.browser_model.fileInfo(index)
        path = file_info.absoluteFilePath()
        self.ui.details.setRootIndex(self.details_model.setRootPath(path))
Exemple #6
0
class FileManager(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(FileManager, self).__init__(parent)
        self.title = 'PyQt5 file system view - pythonspot.com'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.default_path = (os.path.join(os.path.expanduser('~'),
                                          'labvcnc/nc_files/examples'))
        self.user_path = (os.path.join('/media'))
        self.currentPath = None
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files)
        self.model.setNameFilterDisables(False)
        self.model.setNameFilters(["*.ngc", '*.py'])

        self.list = QListView()
        self.list.setModel(self.model)
        self.updateDirectoryView(self.default_path)
        self.list.setWindowTitle("Dir View")
        self.list.resize(640, 480)
        self.list.clicked[QModelIndex].connect(self.clicked)
        self.list.activated.connect(self.load)
        self.list.setAlternatingRowColors(True)

        self.cb = QComboBox()
        self.cb.currentTextChanged.connect(self.filterChanged)
        self.cb.addItems(sorted({'*.ngc', '*.py', '*'}))
        #self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.button = QPushButton()
        self.button.setText('Media')
        self.button.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button.setToolTip('Jump to Media directory')
        self.button.clicked.connect(self.onMediaClicked)

        self.button2 = QPushButton()
        self.button2.setText('User')
        self.button2.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button2.setToolTip('Jump to labvcnc directory')
        self.button2.clicked.connect(self.onUserClicked)

        hbox = QHBoxLayout()
        hbox.addWidget(self.button)
        hbox.addWidget(self.button2)
        hbox.addWidget(self.cb)

        windowLayout = QVBoxLayout()
        windowLayout.addWidget(self.list)
        windowLayout.addLayout(hbox)
        self.setLayout(windowLayout)
        self.show()

    def updateDirectoryView(self, path):
        self.list.setRootIndex(self.model.setRootPath(path))

    def filterChanged(self, text):
        self.model.setNameFilters([text])

    def clicked(self, index):
        # the signal passes the index of the clicked item
        dir_path = self.model.filePath(index)
        if self.model.fileInfo(index).isFile():
            self.currentPath = dir_path
            return
        root_index = self.model.setRootPath(dir_path)
        self.list.setRootIndex(root_index)

    def onMediaClicked(self):
        self.updateDirectoryView(self.user_path)

    def onUserClicked(self):
        self.updateDirectoryView(self.default_path)

    def select_row(self, style):
        style = style.lower()
        selectionModel = self.list.selectionModel()
        row = selectionModel.currentIndex().row()
        self.rows = self.model.rowCount(self.list.rootIndex())

        if style == 'last':
            row = self.rows
        elif style == 'up':
            if row > 0:
                row -= 1
            else:
                row = 0
        elif style == 'down':
            if row < self.rows:
                row += 1
            else:
                row = self.rows
        else:
            return
        top = self.model.index(row, 0, self.list.rootIndex())
        selectionModel.setCurrentIndex(
            top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    def _hal_init(self):
        if self.PREFS_:
            last_path = self.PREFS_.getpref('last_file_path',
                                            self.default_path, str,
                                            'BOOK_KEEPING')
            self.updateDirectoryView(last_path)
            LOG.debug("lAST FILE PATH: {}".format(last_path))
        else:
            LOG.debug("lAST FILE PATH: {}".format(self.default_path))
            self.updateDirectoryView(self.default_path)

    # get current selection and update the path
    # then if the path is good load it into labvcnc
    # record it in the preference file if available
    def load(self):
        row = self.list.selectionModel().currentIndex()
        self.clicked(row)

        fname = self.currentPath
        if fname is None:
            return
        if fname:
            if self.PREFS_:
                self.PREFS_.putpref('last_file_path', fname, str,
                                    'BOOK_KEEPING')
            ACTION.OPEN_PROGRAM(fname)
            STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME')

    def up(self):
        self.select_row('up')

    def down(self):
        self.select_row('down')
Exemple #7
0
class FileManager(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(FileManager, self).__init__(parent)
        self.title = 'Qtvcp File System View'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self._last = 0

        if INFO.PROGRAM_PREFIX is not None:
            self.user_path = os.path.expanduser(INFO.PROGRAM_PREFIX)
        else:
            self.user_path = (os.path.join(os.path.expanduser('~'),
                                           'linuxcnc/nc_files'))
        user = os.path.split(os.path.expanduser('~'))[-1]
        self.media_path = (os.path.join('/media', user))
        temp = [('User', self.user_path), ('Media', self.media_path)]
        self._jumpList = OrderedDict(temp)
        self.currentPath = None
        self.currentFolder = None
        self.PREFS_ = None
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        pasteBox = QHBoxLayout()
        self.textLine = QLineEdit()
        self.textLine.setToolTip('Current Director/selected File')
        self.pasteButton = QToolButton()
        self.pasteButton.setEnabled(False)
        self.pasteButton.setText('Paste')
        self.pasteButton.setToolTip(
            'Copy file from copy path to current directory/file')
        self.pasteButton.clicked.connect(self.paste)
        self.pasteButton.hide()
        pasteBox.addWidget(self.textLine)
        pasteBox.addWidget(self.pasteButton)

        self.copyBox = QFrame()
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        self.copyLine = QLineEdit()
        self.copyLine.setToolTip('File path to copy from, when pasting')
        self.copyButton = QToolButton()
        self.copyButton.setText('Copy')
        self.copyButton.setToolTip('Record current file as copy path')
        self.copyButton.clicked.connect(self.recordCopyPath)
        hbox.addWidget(self.copyButton)
        hbox.addWidget(self.copyLine)
        self.copyBox.setLayout(hbox)
        self.copyBox.hide()

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files)
        self.model.setNameFilterDisables(False)
        self.model.rootPathChanged.connect(self.folderChanged)

        self.list = QListView()
        self.list.setModel(self.model)
        self.list.resize(640, 480)
        self.list.clicked[QModelIndex].connect(self.listClicked)
        self.list.activated.connect(self._getPathActivated)
        self.list.setAlternatingRowColors(True)
        self.list.hide()

        self.table = QTableView()
        self.table.setModel(self.model)
        self.table.resize(640, 480)
        self.table.clicked[QModelIndex].connect(self.listClicked)
        self.table.activated.connect(self._getPathActivated)
        self.table.setAlternatingRowColors(True)

        header = self.table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        header.swapSections(1, 3)
        header.setSortIndicator(1, Qt.AscendingOrder)

        self.table.setSortingEnabled(True)
        self.table.setColumnHidden(2, True)  # type
        self.table.verticalHeader().setVisible(False)  # row count header

        self.cb = QComboBox()
        self.cb.currentIndexChanged.connect(self.filterChanged)
        self.fillCombobox(INFO.PROGRAM_FILTERS_EXTENSIONS)
        self.cb.setMinimumHeight(30)
        self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,
                                          QSizePolicy.Fixed))

        self.button2 = QToolButton()
        self.button2.setText('User')
        self.button2.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button2.setMinimumSize(60, 30)
        self.button2.setToolTip(
            'Jump to User directory.\nLong press for Options.')
        self.button2.clicked.connect(self.onJumpClicked)

        self.button3 = QToolButton()
        self.button3.setText('Add Jump')
        self.button3.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button3.setMinimumSize(60, 30)
        self.button3.setToolTip('Add current directory to jump button list')
        self.button3.clicked.connect(self.onActionClicked)

        self.settingMenu = QMenu(self)
        self.button2.setMenu(self.settingMenu)

        hbox = QHBoxLayout()
        hbox.addWidget(self.button2)
        hbox.addWidget(self.button3)
        hbox.insertStretch(2, stretch=0)
        hbox.addWidget(self.cb)

        windowLayout = QVBoxLayout()
        windowLayout.addLayout(pasteBox)
        windowLayout.addWidget(self.copyBox)
        windowLayout.addWidget(self.list)
        windowLayout.addWidget(self.table)
        windowLayout.addLayout(hbox)
        self.setLayout(windowLayout)
        self.show()

    def _hal_init(self):
        if self.PREFS_:
            last_path = self.PREFS_.getpref('last_loaded_directory',
                                            self.user_path, str,
                                            'BOOK_KEEPING')
            LOG.debug("lAST FILE PATH: {}".format(last_path))
            if not last_path == '':
                self.updateDirectoryView(last_path)
            else:
                self.updateDirectoryView(self.user_path)

            # get all the saved jumplist paths
            temp = self.PREFS_.getall('FILEMANAGER_JUMPLIST')
            self._jumpList.update(temp)

        else:
            LOG.debug("lAST FILE PATH: {}".format(self.user_path))
            self.updateDirectoryView(self.user_path)

        # install jump paths into toolbutton menu
        for i in self._jumpList:
            self.addAction(i)

        # set recorded columns sort settings
        self.SETTINGS_.beginGroup("FileManager-{}".format(self.objectName()))
        sect = self.SETTINGS_.value('sortIndicatorSection', type=int)
        order = self.SETTINGS_.value('sortIndicatorOrder', type=int)
        self.SETTINGS_.endGroup()
        if not None in (sect, order):
            self.table.horizontalHeader().setSortIndicator(sect, order)

    # when qtvcp closes this gets called
    # record jump list paths
    def _hal_cleanup(self):
        if self.PREFS_:
            for i, key in enumerate(self._jumpList):
                if i in (0, 1):
                    continue
                self.PREFS_.putpref(key, self._jumpList.get(key), str,
                                    'FILEMANAGER_JUMPLIST')

        # record sorted columns
        h = self.table.horizontalHeader()
        self.SETTINGS_.beginGroup("FileManager-{}".format(self.objectName()))
        self.SETTINGS_.setValue('sortIndicatorSection',
                                h.sortIndicatorSection())
        self.SETTINGS_.setValue('sortIndicatorOrder', h.sortIndicatorOrder())
        self.SETTINGS_.endGroup()

    #########################
    # callbacks
    #########################

    # add shown text and hidden filter data from the INI
    def fillCombobox(self, data):
        for i in data:
            self.cb.addItem(i[0], i[1])

    def folderChanged(self, data):
        data = os.path.normpath(data)
        self.currentFolder = data
        self.textLine.setText(data)

    def updateDirectoryView(self, path, quiet=False):
        if os.path.exists(path):
            self.list.setRootIndex(self.model.setRootPath(path))
            self.table.setRootIndex(self.model.setRootPath(path))
        else:
            LOG.debug(
                "Set directory view error - no such path {}".format(path))
            if not quiet:
                STATUS.emit(
                    'error', LOW_ERROR,
                    "File Manager error - No such path: {}".format(path))

    # retrieve selected filter (it's held as QT.userData)
    def filterChanged(self, index):
        userdata = self.cb.itemData(index)
        self.model.setNameFilters(userdata)

    def listClicked(self, index):
        # the signal passes the index of the clicked item
        dir_path = os.path.normpath(self.model.filePath(index))
        if self.model.fileInfo(index).isFile():
            self.currentPath = dir_path
            self.textLine.setText(self.currentPath)
            return
        root_index = self.model.setRootPath(dir_path)
        self.list.setRootIndex(root_index)
        self.table.setRootIndex(root_index)

    def onUserClicked(self):
        self.showUserDir()

    def onMediaClicked(self):
        self.showMediaDir()

    # jump directly to a saved path shown on the button
    def onJumpClicked(self):
        data = self.button2.text()
        if data.upper() == 'MEDIA':
            self.showMediaDir()
        elif data.upper() == 'USER':
            self.showUserDir()
        else:
            temp = self._jumpList.get(data)
            if temp is not None:
                self.updateDirectoryView(temp)
            else:
                STATUS.emit('error', linuxcnc.OPERATOR_ERROR,
                            'file jumopath: {} not valid'.format(data))
                log.debug('file jumopath: {} not valid'.format(data))

    # jump directly to a saved path from the menu
    def jumpTriggered(self, data):
        if data.upper() == 'MEDIA':
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip(
                'Jump to Media directory.\nLong press for Options.')
            self.showMediaDir()
        elif data.upper() == 'USER':
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip(
                'Jump to User directory.\nLong press for Options.')
            self.showUserDir()
        else:
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip('Jump to directory:\n{}'.format(
                self._jumpList.get(data)))
            self.updateDirectoryView(self._jumpList.get(data))

    # add a jump list path
    def onActionClicked(self):
        i = self.currentFolder
        try:
            self._jumpList[i] = i
        except Exception as e:
            print(e)
        button = QAction(QIcon.fromTheme('user-home'), i, self)
        # weird lambda i=i to work around 'function closure'
        button.triggered.connect(lambda state, i=i: self.jumpTriggered(i))
        self.settingMenu.addAction(button)

    # get current selection and update the path
    # then if the path is good load it into linuxcnc
    # record it in the preference file if available
    def _getPathActivated(self):
        if self.list.isVisible():
            row = self.list.selectionModel().currentIndex()
        else:
            row = self.table.selectionModel().currentIndex()
            self.listClicked(row)

        fname = self.currentPath
        if fname is None:
            return
        if fname:
            self.load(fname)

    def recordCopyPath(self):
        data, isFile = self.getCurrentSelected()
        if isFile:
            self.copyLine.setText(os.path.normpath(data))
            self.pasteButton.setEnabled(True)
        else:
            self.copyLine.setText('')
            self.pasteButton.setEnabled(False)
            STATUS.emit('error', OPERATOR_ERROR,
                        'Can only copy a file, not a folder')

    def paste(self):
        res = self.copyFile(self.copyLine.text(), self.textLine.text())
        if res:
            self.copyLine.setText('')
            self.pasteButton.setEnabled(False)

    ########################
    # helper functions
    ########################

    def addAction(self, i):
        axisButton = QAction(QIcon.fromTheme('user-home'), i, self)
        # weird lambda i=i to work around 'function closure'
        axisButton.triggered.connect(lambda state, i=i: self.jumpTriggered(i))
        self.settingMenu.addAction(axisButton)

    def showList(self, state=True):
        if state:
            self.table.hide()
            self.list.show()
        else:
            self.table.show()
            self.list.hide()

    def showTable(self, state=True):
        self.showList(not state)

    def showCopyControls(self, state):
        if state:
            self.copyBox.show()
            self.pasteButton.show()
        else:
            self.copyBox.hide()
            self.pasteButton.hide()

    def showMediaDir(self, quiet=False):
        self.updateDirectoryView(self.media_path, quiet)

    def showUserDir(self, quiet=False):
        self.updateDirectoryView(self.user_path, quiet)

    def copyFile(self, s, d):
        try:
            shutil.copy(s, d)
            return True
        except Exception as e:
            LOG.error("Copy file error: {}".format(e))
            STATUS.emit('error', OPERATOR_ERROR,
                        "Copy file error: {}".format(e))
            return False

    @pyqtSlot(float)
    @pyqtSlot(int)
    def scroll(self, data):
        if data > self._last:
            self.up()
        elif data < self._last:
            self.down()
        self._last = data

    # moves the selection up
    # used with MPG scrolling
    def up(self):
        self.select_row('up')

    # moves the selection down
    # used with MPG scrolling
    def down(self):
        self.select_row('down')

    def select_row(self, style='down'):
        style = style.lower()
        if self.list.isVisible():
            i = self.list.rootIndex()
            selectionModel = self.list.selectionModel()
        else:
            i = self.table.rootIndex()
            selectionModel = self.table.selectionModel()

        row = selectionModel.currentIndex().row()
        self.rows = self.model.rowCount(i)

        if style == 'last':
            row = self.rows
        elif style == 'up':
            if row > 0:
                row -= 1
            else:
                row = 0
        elif style == 'down':
            if row < self.rows - 1:
                row += 1
            else:
                row = self.rows - 1
        else:
            return
        top = self.model.index(row, 0, i)
        selectionModel.setCurrentIndex(
            top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    # returns the current highlighted (selected) path as well as
    # whether it's a file or not.
    def getCurrentSelected(self):
        if self.list.isVisible():
            selectionModel = self.list.selectionModel()
        else:
            selectionModel = self.table.selectionModel()
        index = selectionModel.currentIndex()
        dir_path = os.path.normpath(self.model.filePath(index))
        if self.model.fileInfo(index).isFile():
            return (dir_path, True)
        else:
            return (dir_path, False)

    # This can be class patched to do something else
    def load(self, fname=None):
        try:
            if fname is None:
                self._getPathActivated()
                return
            self.recordBookKeeping()
            ACTION.OPEN_PROGRAM(fname)
            STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME')
        except Exception as e:
            LOG.error("Load file error: {}".format(e))
            STATUS.emit('error', NML_ERROR, "Load file error: {}".format(e))

    # This can be class patched to do something else
    def recordBookKeeping(self):
        fname = self.currentPath
        if fname is None:
            return
        if self.PREFS_:
            self.PREFS_.putpref('last_loaded_directory', self.model.rootPath(),
                                str, 'BOOK_KEEPING')
            self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING')
Exemple #8
0
class MyWindow(QMainWindow, Form):
    def __init__(self):
        Form.__init__(self)
        QMainWindow.__init__(self)
        self.setupUi(self)

        self.setWindowTitle("Automated Homework Correction")

        # Initializations for the student table on the left
        self.st_table = MyTable(self)
        self.st_tab_ind = None  # stores the table col. index/text
        self.persian_font = QFont()  # Holds the persian font for the table
        self.setup_st_table()
        QVBoxLayout(self.table_frame).addWidget(self.st_table)

        # Initializations for the Terminal in Terminal tab
        self.setup_terminal()

        # Initializations for the part below terminal
        self.open_code_push_button.clicked.connect(self.open_code)
        self.open_report_push_button.clicked.connect(self.open_report)
        self.compile_push_button.clicked.connect(self.compile_hw)
        self.run_push_button.clicked.connect(self.run_hw)
        self.prog_type_combo.activated.connect(self.prog_type_changed)
        self.sel_prog_type = self.prog_type_combo.currentText()

        # Initializations for the Folder Tree in Folder Tab
        self.folder_model = QFileSystemModel()
        self.setup_folder_tree_view()

        # Miscellaneous initializations
        self.command = ""  # holds the text in console textbox
        self.hw_path = ""  # holds the dropped hw folder path
        self.sel_hw_path = ""  # path of selected hw in the student table
        self.sel_cn = ""  # Selected course name in the cell
        self.sel_hw_num = 0  # hw num of selected cell
        self.sel_st_num = 0  # student number of selected cell
        self.hw_folders = []  # proper and valid homework folders
        self.prev_row = -1  # holds the previous selected row of table
        self.sep = "----------------------------------------------------"
        self.hw_re = re.compile(r"\A(\w{2})[-_](HW(\d+)[-_](\d{7}))\Z",
                                re.IGNORECASE)
        self.sel_folder_index = None  # index of the folder model for treeView

        self.zip_thread = None  # will hold the ZipHandle Thread

        # Compiler initializations
        self.c_comp = CCompiler(None)   # will hold the C Compiler handle
        self.c_comp.log_trigger.connect(self.compile_box_update)
        self.mat_compiler = MATCompiler(None)
        self.mat_compiler.log_trigger.connect(self.compile_box_update)

        # OS Specific Initializations
        self._processes = []  # holds all active processes for Popen
        self._plat = platform.system()  # Linux or Windows
        self.system_arch = platform.machine()  # x86_64 or i386

        if "Windows" in self._plat:
            self.is_linux = False   # Used later to know if on linux
            self.is_windows = True
            # Windows code editor
            self.editor = "\"C:\\Program Files\\Sublime Text 3\\subl.exe\" --wait"
            self.terminal_cmd = r"C:\Windows\System32\cmd.exe /k"
            self.pdf_viewer = "\"C:\Program Files (x86)\Adobe\Acrobat DC\Acrobat\Acrobat.exe\""
        
        elif "Linux" in self._plat:
            self.is_linux = True
            self.is_windows = False
            self.editor = "/usr/bin/subl --wait"
            self.pdf_viewer = "/usr/bin/evince"
            self.terminal_cmd = None
        else:
            print("Not a standard OS: use Windows or Linux.")

    def setup_st_table(self):
        """ This function is for setting up the table on the left
            of the dialogue. All initializations are made here."""
        self.st_table.dropped_trigger = self.process_hw  # file/folder dropped
        self.st_table.cellClicked.connect(self.hw_clicked)  # a cell is clicked

        self.st_table.setSelectionMode(PyQt5.QtWidgets.QAbstractItemView.
                                       SingleSelection)
        self.st_table.setSelectionBehavior(PyQt5.QtWidgets.QAbstractItemView.
                                           SelectRows)
        # start out with 5 columns
        self.st_tab_ind = {"CN": 0, "HW_Num": 1, "St_Num": 2, "St_Name": 3,
                           "Folders": 4, "Report": 5}
        self.st_table.setColumnCount(len(self.st_tab_ind))
        # Now put text for the columns and set width if required
        self.st_table.setHorizontalHeaderItem(self.st_tab_ind["CN"],
                                              QTableWidgetItem("CN"))
        self.st_table.setColumnWidth(self.st_tab_ind["CN"], 30)
        self.st_table.setHorizontalHeaderItem(self.st_tab_ind["HW_Num"],
                                              QTableWidgetItem("HW"))
        self.st_table.setColumnWidth(self.st_tab_ind["HW_Num"], 31)
        self.st_table.setHorizontalHeaderItem(self.st_tab_ind["St_Num"],
                                              QTableWidgetItem("St. Num"))
        self.st_table.setColumnWidth(self.st_tab_ind["St_Num"], 70)
        self.st_table.setHorizontalHeaderItem(self.st_tab_ind["St_Name"],
                                              QTableWidgetItem("St. Name"))
        self.st_table.setColumnWidth(self.st_tab_ind["St_Name"], 105)
        self.st_table.setHorizontalHeaderItem(self.st_tab_ind["Folders"],
                                              QTableWidgetItem("Folders"))
        self.st_table.setColumnWidth(self.st_tab_ind["Folders"], 100)
        self.st_table.setHorizontalHeaderItem(self.st_tab_ind["Report"],
                                              QTableWidgetItem("Report"))
        self.st_table.setColumnWidth(self.st_tab_ind["Report"], 100)

        self.persian_font.setFamily("XW Zar")  # Persian font setup for the table
        self.persian_font.setPointSize(11)

    def setup_terminal(self):
        self.compile_box.setTextColor(QColor(237, 238, 240))
        self.compile_box.setText("Drag your folder to the table ...")

    def setup_folder_tree_view(self):
        self.folder_tree_view.setModel(self.folder_model)
        self.folder_tree_view.doubleClicked.connect(self.open_file_folder)
        self.folder_tree_view.expanded.connect(self.expanded)
        self.folder_tree_view.setColumnWidth(0, 350)
        self.folder_tree_view.setColumnWidth(1, 50)
        self.folder_tree_view.setColumnWidth(2, 50)
        self.folder_tree_view.hideColumn(3)

    def enable_config(self, yes):
        """ This functions enables the config part if yes is true """
        items = [self.open_code_push_button, self.run_push_button,
                 self.open_report_push_button, self.compile_push_button,
                 self.prog_type_combo]
        if yes:
            method = methodcaller('setEnabled', True)
        else:
            method = methodcaller('setEnabled', False)
        list(map(method, items))  # Runs setEnabled on all of the items

    @pyqtSlot(str)
    def process_hw(self, path):  # path is DROPPED into the table
        self.hw_path = path.strip()  # removes \n etc
        # a little clean up is necessary for the path
        self.hw_path = os.path.normpath(self.hw_path).lstrip("file:")
        if self.is_linux:
            self.hw_path = os.path.join('/', self.hw_path)  # put a / at start
        elif self.is_windows:  # / should be \
            self.hw_path = self.hw_path.replace('/', os.sep).lstrip(os.sep)

        # Update the folder tree table
        self.folder_model.setRootPath(self.hw_path)
        self.folder_tree_view.setRootIndex(self.folder_model.index(self.hw_path))

        self.hw_folders.clear()  # clear previous homework folders(if any)
        self.st_table.clearContents()  # table contents(if any) not col. headers
        self.command = ""  # reset the console output

        if os.path.isfile(path): # TODO: single file HW
            print("Single File is not yet implemented")
        self.compile_box_update(self.hw_path)  # put folder path in terminal
        
        # Retrieve the zip files only and sort them
        files = os.listdir(self.hw_path)
        files = [f for f in files if f.lower().endswith(".zip")]
        files.sort()

        # Setting up the zip thread
        self.zip_thread = ZipHandle(self.hw_path, files, self.hw_re)
        self.zip_thread.log_trigger.connect(self.compile_box_update)
        self.zip_thread.hw_add_trigger.connect(self.table_hw_add)
        self.zip_thread.start()

    @pyqtSlot(int, int)
    def hw_clicked(self, row, _):
        """ A Cell is clicked, row, col is also passed in here """
        if row == self.prev_row:  # if double selecting a row, deselect
            self.st_table.clearSelection()
            self.prev_row = -1
            self.enable_config(False)
            return
        else:
            self.prev_row = row

        # We use this event handler since it does similar thing
        self.closeEvent(None)

        # Retrieve other information of the hw from different columns
        self.sel_cn = self.st_table.item(row, self.st_tab_ind["CN"]).text()
        self.sel_hw_num = self.st_table.item(row, self.st_tab_ind["HW_Num"]).text()
        self.sel_st_num = self.st_table.item(row, self.st_tab_ind["St_Num"]).text()

        # This part updates the folder tree
        self.sel_hw_path = os.path.join(self.hw_path, "{}-HW{}-{}".format(
            self.sel_cn, self.sel_hw_num, self.sel_st_num))
        folder_index = self.folder_model.index(self.sel_hw_path)
        self.folder_tree_view.collapseAll()
        self.folder_tree_view.expand(folder_index)  # triggers expanded

        # Enabling the buttons below terminal
        self.enable_config(True)

    @pyqtSlot()
    def open_code(self):
        """ This event handler is run whenever user clicks open code button"""
        # TODO: Add support for the editor if in other directories
        p = Popen(shlex.split(self.editor + ' "' + self.sel_hw_path + '"'),
                  shell=False, start_new_session=True)  # open code editor
        self._processes.append(p)

    @pyqtSlot()
    def open_report(self):
        row = self.st_table.currentRow()
        sel_rep_name = self.st_table.item(row, self.st_tab_ind["Report"]).text()
        if sel_rep_name == "N/A":
            self.compile_box_update("Can not find report file.")
            return
        sel_report_path = os.path.join(self.sel_hw_path, sel_rep_name)
        pdf_cmd = shlex.split(self.pdf_viewer)
        pdf_cmd.extend([sel_report_path])
        p = Popen(pdf_cmd, shell=False, start_new_session=True)  # open pdf
        self._processes.append(p)

    @pyqtSlot(int)
    def prog_type_changed(self, index):
        self.sel_prog_type = self.prog_type_combo.currentText()
        if self.sel_prog_type != "C++":  # No compilation step except C++
            self.compile_push_button.setVisible(False)
        else:
            self.compile_push_button.setVisible(True)

    @pyqtSlot()
    def compile_hw(self):  # Compile push button is clicked
        """ In this function the selected hw path is compiled. """
        if self.sel_prog_type == "C++":
            self.c_comp.change_root(self.sel_hw_path)
            self.compile_box_update("{}: C++".format(os.path.basename(
                self.sel_hw_path)))
            self.compile_box_update("Generating Makefile if needed ...")
            self.c_comp.generate_makefiles()
            self.compile_box_update("\nCompiling the Questions, Wait ...")
            self.c_comp.compile()  # compiles all the folders with proper C++
        elif self.sel_prog_type == "Matlab":
            pass
        elif self.sel_prog_type == "Python":
            pass

    @pyqtSlot()
    def run_hw(self):
        """ This function is run when user clicks on Run button """
        if self.sel_prog_type == "C++":
            comp = self.c_comp
        elif self.sel_prog_type == "Python": # comp = self.py_comp
            pass
        elif self.sel_prog_type == "Matlab":
            comp = self.mat_compiler
            comp.change_root(self.sel_hw_path)
            script_files = self.mat_compiler.search_scripts()
            if len(script_files) == 0:
                self.compile_box_update("Did not find any script to run.")
                return

        self.compile_box_update("{}: Execute".format(self.sel_prog_type))
        comp.exec()  # execute proper compiler
        self.compile_box_update("{0}\n{0}".format(self.sep))

    @pyqtSlot(QModelIndex)
    def expanded(self, index):  # Tree view is expanded at one of the indexes
        # Disable this line, since it decreases the width, 1 level is only open
        # self.folder_tree_view.resizeColumnToContents(0)
        if index != None:
            self.folder_tree_view.setCurrentIndex(index)
            self.folder_tree_view.scrollTo(index)

    @pyqtSlot(QModelIndex)
    def open_file_folder(self, index):  # double clicked on something
        """ This function can open certian filetypes. A handler needs to open the
            file. For the moment only pdf files are opened."""
        path = self.folder_model.fileInfo(index).absoluteFilePath()
        if os.path.isdir(path): # No need to do anything
            return
        if self.is_linux:
            if path.lower().endswith(".pdf"):
                p = Popen(shlex.split(self.pdf_viewer + "\"" + path + "\""),
                          shell=False, start_new_session=True)
                self._processes.append(p)

    def table_hw_add(self, hw_folder):
        self.hw_folders.append(hw_folder)
        hw_ls = os.listdir(os.path.join(self.hw_path, hw_folder))
        hw_dirs = [item for item in hw_ls if
                   os.path.isdir(os.path.join(self.hw_path, hw_folder, item))]
        hw_files = [item for item in hw_ls if
                   os.path.isfile(os.path.join(self.hw_path, hw_folder, item))]
        course_name, file_name, hw_num, st_num = self.hw_re.match(
            hw_folder).groups()

        cur_row = len(self.hw_folders) - 1
        self.st_table.insertRow(cur_row)
        self.st_table.setItem(cur_row, self.st_tab_ind["CN"],
                              QTableWidgetItem(course_name))  # hw_num
        self.st_table.item(cur_row, self.st_tab_ind["CN"]).\
            setTextAlignment(QtCore.Qt.AlignCenter)
        self.st_table.setItem(cur_row, self.st_tab_ind["HW_Num"],
                              QTableWidgetItem(hw_num))  # hw_num
        self.st_table.item(cur_row, self.st_tab_ind["HW_Num"]).\
            setTextAlignment(QtCore.Qt.AlignCenter)
        self.st_table.setItem(cur_row, self.st_tab_ind["St_Num"],
                              QTableWidgetItem(st_num))  # st_num
        self.st_table.item(cur_row, self.st_tab_ind["St_Num"]). \
            setTextAlignment(QtCore.Qt.AlignCenter)
        st_name_item = QTableWidgetItem("وارد نشده است")
        st_name_item.setFont(self.persian_font)
        self.st_table.setItem(cur_row, self.st_tab_ind["St_Name"], st_name_item)
        self.st_table.item(cur_row, self.st_tab_ind["St_Name"]). \
            setTextAlignment(QtCore.Qt.AlignHCenter)

        # ignore chars from the homework folder names in the table,
        # e.g.: Q1, Q2 -> 1, 2
        if len(hw_dirs) > 0:
            hw_dirs_str = ' '.join(hw_dirs)
            hw_dirs_str = [c for c in hw_dirs_str if not c.isalpha()]
            hw_dirs_str.sort()
            hw_dirs_str = ' '.join(hw_dirs_str)  # convert back to str
        else:
            hw_dirs_str = "N/A"
        self.st_table.setItem(cur_row, self.st_tab_ind["Folders"],
                              QTableWidgetItem(hw_dirs_str)) # hw folders

        # Finding the report file name and store in report_file variable
        if len(hw_files) > 0:
            # filter out non pdf files
            hw_files = [f for f in hw_files if f.lower().endswith(".pdf")]
            if len(hw_files) > 1:
                self.compile_box_update("{}: multiple PDFs".format(hw_folder))
            if len(hw_files) > 0:  # can be greater than 1, only output one
                report_file = hw_files[0]
            else:
                report_file = "N/A"
        else:   # No report file available
            report_file = "N/A"
        self.st_table.setItem(cur_row, self.st_tab_ind["Report"],
                              QTableWidgetItem(report_file))
        #QApplication.instance().processEvents()

    def compile_box_update(self, text):
        if text == "":  # Ignore input
            return
        self.command += text + "\n"
        self.compile_box.setText(self.command)
        self.compile_box.moveCursor(PyQt5.QtGui.QTextCursor.End)
        QApplication.instance().processEvents()

    # This is called wihen the dialog is closed by pressing x
    def closeEvent(self, event):
        self.c_comp.kill_windows()
        self.mat_compiler.kill_windows()
        if self.is_linux:
            for p in self._processes:
                os.killpg(os.getpgid(p.pid), signal.SIGTERM)
            self._processes.clear()
        elif self.is_windows: # TODO: Add support for windows
            pass
class App(QMainWindow, QWidget):  # 창의 대부분의 기능
    def __init__(self):  # 창 기본 세팅 설정
        super().__init__()

        # Window options!
        self.title = 'HexQT'
        self.left = 0
        self.top = 0
        self.width = 1280
        self.height = 840

        self.rowSpacing = 4  # How many bytes before a double space.
        self.rowLength = 16  # 헥사 창에 얼마나 많은 byte 가 들어갈 것인지
        self.byteWidth = 4  # How many bits to include in a byte.
        self.mode = Mode.READ

        self.initUI()

    def openFile(self):
        fileSelect = FileSelector()
        fileName = fileSelect.fileName

        self.readFile(fileName)

    # readFile ... Reads file data from a file in the form of bytes and generates the text for the hex-editor.
    def readFile(self, fileName):
        fileData = ''
        if fileName:
            with open(fileName, 'rb') as fileObj:
                fileData = fileObj.read()
                self.generateView(fileData)
        # saveFile ... Method for saving the edited hex file.

    def saveFile(self):
        print('Saved!')

    # generateView ... Generates text view for hexdump likedness.
    def generateView(self, text):
        space = ' '
        bigSpace = ' ' * 4

        rowSpacing = self.rowSpacing
        rowLength = self.rowLength

        offset = 0

        offsetText = ''
        mainText = ''
        asciiText = ''

        for chars in range(1, len(text) + 1):
            byte = text[chars - 1]
            char = chr(text[chars - 1])

            # Asciitext 는 오른쪽 출력부
            if char is ' ':
                asciiText += '.'

            elif char is '\n':
                asciiText += '!'

            else:
                asciiText += char
            # main text 가 중앙에 있는것
            mainText += format(byte, '0' + str(self.byteWidth) + 'x')

            if chars % rowLength is 0:
                offsetText += format(offset, '08x') + '\n'
                mainText += '\n'
                asciiText += '\n'

            elif chars % rowSpacing is 0:
                mainText += space * 2

            else:
                mainText += space

            offset += len(char)

        self.offsetTextArea.setText(offsetText)
        self.mainTextArea.setText(mainText)
        self.asciiTextArea.setText(asciiText)

    # openFile ... Opens a file directory and returns the filename.

    # highlightMain ... Bi-directional highlighting from main.
    def highlightMain(self):
        # Create and get cursors for getting and setting selections.
        highlightCursor = QTextCursor(self.asciiTextArea.document())
        # asciitextArea의 처음을 가르치는 커서를 구성
        cursor = self.mainTextArea.textCursor()
        # 커서의 위치의 사본을 따서 복사 함
        # Clear any current selections and reset text color.
        highlightCursor.select(QTextCursor.Document)
        highlightCursor.setCharFormat(QTextCharFormat())
        highlightCursor.clearSelection()

        # Information about where selections and rows start.
        selectedText = cursor.selectedText()  # The actual text selected.
        selectionStart = cursor.selectionStart()
        selectionEnd = cursor.selectionEnd()

        mainText = self.mainTextArea.toPlainText().replace('\n', 'A')
        #mainText = self.mainTextArea.toPlainText()

        totalBytes = 0

        for char in mainText[selectionStart:selectionEnd]:
            if char is not ' ':
                totalBytes += len(char)

        asciiStart = 0

        for char in mainText[:selectionStart]:
            if char is not ' ':
                asciiStart += len(char)

        totalBytes = round(totalBytes / self.byteWidth)
        asciiStart = round(asciiStart / self.byteWidth)
        asciiEnd = asciiStart + totalBytes

        asciiText = self.asciiTextArea.toPlainText()

        # Select text and highlight it.
        highlightCursor.setPosition(asciiStart, QTextCursor.MoveAnchor)
        highlightCursor.setPosition(asciiEnd, QTextCursor.KeepAnchor)

        highlight = QTextCharFormat()
        highlight.setBackground(Qt.darkCyan)
        highlightCursor.setCharFormat(highlight)
        highlightCursor.clearSelection()

    # highlightAscii ... Bi-directional highlighting from ascii.
    def highlightAscii(self):
        selectedText = self.asciiTextArea.textCursor().selectedText()

    # offsetJump ... Creates a dialogue and gets the offset to jump to and then jumps to that offset.

    def offsetJump(self):  # input dialog 를 활용 하여 jump to ofsset 을 만듭니다.
        jumpText = InputDialogue('Jump to Offset', 'Offset').dialogueReponse
        jumpOffset = 0xF

        mainText = self.mainTextArea.toPlainText()
        mainText = mainText.strip().replace('  ', ' ')

        textCursor = self.mainTextArea.textCursor()

    # createMainView ... Creates the primary view and look of the application (3-text areas.)

    def createMainView(self):
        qhBox = QHBoxLayout()
        qhBox2 = QHBoxLayout()
        qvBox = QVBoxLayout()

        self.dirModel = QFileSystemModel()
        self.dirModel.setRootPath('')
        self.fileModel = QFileSystemModel()
        self.tree = QTreeView()
        self.list = QListView()
        self.tree.setModel(self.dirModel)
        self.list.setModel(self.fileModel)

        self.tree.clicked.connect(self.tree_on_clicked)
        self.list.clicked.connect(self.list_on_clicked)

        self.mainTextArea = QTextEdit()
        self.offsetTextArea = QTextEdit()
        self.asciiTextArea = QTextEdit()

        # Initialize them all to read only.
        self.mainTextArea.setReadOnly(True)
        self.asciiTextArea.setReadOnly(True)
        self.offsetTextArea.setReadOnly(True)

        # Create the fonts and styles to be used and then apply them.
        font = QFont("DejaVu Sans Mono", 11, QFont.Normal, True)

        self.mainTextArea.setFont(font)
        self.asciiTextArea.setFont(font)
        self.offsetTextArea.setFont(font)

        #self.offsetTextArea.setTextColor(Qt.red)

        # Syncing scrolls.
        syncScrolls(self.mainTextArea, self.asciiTextArea, self.offsetTextArea)

        # Highlight linking. BUG-GY
        self.mainTextArea.selectionChanged.connect(self.highlightMain)
        self.asciiTextArea.selectionChanged.connect(self.highlightAscii)

        qhBox.addWidget(self.offsetTextArea, 1)
        qhBox.addWidget(self.mainTextArea, 6)
        qhBox.addWidget(self.asciiTextArea, 2)
        qhBox2.addWidget(self.tree)
        qhBox2.addWidget(self.list)
        qvBox.addLayout(qhBox2)
        qvBox.addLayout(qhBox)
        return qvBox

    def tree_on_clicked(self, index):
        path = self.dirModel.fileInfo(index).absoluteFilePath()
        self.list.setRootIndex(self.fileModel.setRootPath(path))

    def list_on_clicked(self, index):
        path = self.fileModel.fileInfo(index).absoluteFilePath()
        #self.openbyList(self,path)
        self.readFile(path)

    # initUI ... Initializes the min look of the application.
    def initUI(self):
        # Initialize basic window options.
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        # Center the window.
        qtRectangle = self.frameGeometry()
        centerPoint = QDesktopWidget().availableGeometry().center()
        qtRectangle.moveCenter(centerPoint)
        self.move(qtRectangle.topLeft())

        # Creates a menu bar, (file, edit, options, etc...)
        mainMenu = self.menuBar()

        # Menus for window.
        fileMenu = mainMenu.addMenu('File')
        editMenu = mainMenu.addMenu('Edit')
        viewMenu = mainMenu.addMenu('View')
        helpMenu = mainMenu.addMenu('Help')

        # FILE MENU ---------------------------------------

        # Open button.
        openButton = QAction(QIcon(), 'Open', self)
        openButton.setShortcut('Ctrl+O')
        openButton.setStatusTip('Open file')
        openButton.triggered.connect(self.openFile)

        # Save button.
        saveButton = QAction(QIcon(), 'Save', self)
        saveButton.setShortcut('Ctrl+S')
        saveButton.setStatusTip('Open file')
        saveButton.triggered.connect(self.saveFile)

        # Optional exit stuff.
        exitButton = QAction(QIcon(), 'Exit', self)
        exitButton.setShortcut('Ctrl+Q')
        exitButton.setStatusTip('Exit application')
        exitButton.triggered.connect(self.close)

        fileMenu.addAction(openButton)
        fileMenu.addAction(saveButton)
        fileMenu.addAction(exitButton)

        # EDIT MENU ---------------------------------------

        # Jump to Offset
        offsetButton = QAction(QIcon(), 'Jump to Offset', self)
        offsetButton.setShortcut('Ctrl+J')
        offsetButton.setStatusTip('Jump to Offset')
        offsetButton.triggered.connect(self.offsetJump)

        editMenu.addAction(offsetButton)

        # Creating a widget for the central widget thingy.
        centralWidget = QWidget()
        centralWidget.setLayout(self.createMainView())

        self.setCentralWidget(centralWidget)

        # Show our masterpiece.
        self.show()
Exemple #10
0
class FileBrowser(QTreeView):
    def __init__(self,
                 parent=None,
                 textPad=None,
                 notebook=None,
                 codeView=None):
        super().__init__()
        self.path = self.checkPath(os.getcwd())
        self.filename = None

        self.text = None

        self.initItems()

        self.textPad = textPad
        self.notebook = notebook
        self.codeView = codeView

        self.mainWindow = parent

        self.index = None

        self.copySourceFilePath = None  # copy / paste items
        self.copySourceFileName = None
        self.isCopyFileFolder = None

        self.setStyleSheet("""
            border: 5 px;
            background-color: black; 
            color: white;
            alternate-background-color: #FFFFFF;
            selection-background-color: #3b5784;
            """)

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

        self.popMenu = QMenu()
        self.popMenu.setStyleSheet("""
            color: #FFFFFF;
            background-color: #2c2c2c;
            selection-background-color: #3b5784;
            alternate-background-color: #FFFFFF;
        """)

        infoAction = QAction('Info', self)
        infoAction.triggered.connect(self.onInfo)
        createFolderAction = QAction('Create New Folder', self)
        createFolderAction.triggered.connect(self.onCreateNewFolder)
        copyAction = QAction('Copy Item', self)
        copyAction.triggered.connect(self.onCopy)
        pasteAction = QAction('Paste Item', self)
        pasteAction.triggered.connect(self.onPaste)
        renameAction = QAction('Rename Item', self)
        renameAction.triggered.connect(self.onRename)
        deleteAction = QAction('Delete Item', self)
        deleteAction.triggered.connect(self.onDelete)
        terminalAction = QAction('Open Terminal', self)
        terminalAction.triggered.connect(self.onTerminal)

        self.popMenu.addAction(infoAction)
        self.popMenu.addSeparator()
        self.popMenu.addAction(createFolderAction)
        self.popMenu.addSeparator()
        self.popMenu.addAction(copyAction)
        self.popMenu.addAction(pasteAction)
        self.popMenu.addAction(renameAction)
        self.popMenu.addSeparator()
        self.popMenu.addAction(deleteAction)
        self.popMenu.addSeparator()
        self.popMenu.addAction(terminalAction)

    def openMenu(self, position):
        # -> open ContextMenu
        self.popMenu.exec_(self.mapToGlobal(position))

    def onInfo(self):
        if not self.index:
            return

        index = self.index
        indexItem = self.model.index(index.row(), 0, index.parent())

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        bundle = fileInfo.isBundle()  # bool
        dir = fileInfo.isDir()  # bool
        file = fileInfo.isFile()  # bool
        executable = fileInfo.isExecutable()  # bool
        readable = fileInfo.isReadable()  # bool
        writable = fileInfo.isWritable()  # bool
        created = fileInfo.created()  # QDateTime
        #modified = fileInfo.lastModified()      # QDateTime
        owner = fileInfo.owner()  # QString
        size = fileInfo.size()  # QInt
        s = format(size, ',d')

        text = ''
        text += 'Type:\t'
        if bundle:
            text += 'Bundle\n\n'
        if dir:
            text += 'Path\n\n'
        if file:
            text += 'File\n\n'

        if readable:
            text += 'read:\tyes\n'
        else:
            text += 'read:\tno\n'
        if writable:
            text += 'write:\tyes\n'
        else:
            text += 'write:\tno\n'
        if executable:
            text += 'exec:\tyes\n\n'
        else:
            text += 'exec:\tno\n\n'

        text += 'size:\t' + str(s) + ' bytes' + '\n'
        text += 'owner:\t' + owner + '\n'
        text += 'created:\t' + str(created.date().day()) + '.' + \
                str(created.date().month()) + '.' + \
                str(created.date().year()) + '  ' + \
                created.time().toString() + '\n'

        q = MessageBox(QMessageBox.Information, fileName, text,
                       QMessageBox.NoButton)
        q.exec_()

    def onCreateNewFolder(self):
        if not self.index:
            return
        else:
            index = self.index
            fileName, filePath, fileDir, fileInfo = self.getFileInformation()

            path = os.getcwd() + '/'
            path = self.checkPath(path)

        index = self.index
        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        dialog = EnterDialog(self.mainWindow, fileName, \
                             filePath, fileDir, fileInfo, False, path)
        dialog.exec_()

        # return

    def onCopy(self):
        if not self.index:
            return

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        if fileName == '..':
            self.clearSelection()
            self.mainWindow.statusBar.showMessage("can't copy this item !",
                                                  3000)
            self.copySourceFilePath = None
            self.copySourceFileName = None
            self.isCopyFileFolder = None
            return

        if fileDir:
            self.copySourceFilePath = filePath
            self.copySourceFileName = fileName
            self.isCopyFileFolder = True
            self.mainWindow.statusBar.showMessage('Path: <' + \
                                                   self.copySourceFileName + \
                                                   '> marked', 3000)
        else:
            self.copySourceFilePath = filePath
            self.copySourceFileName = fileName
            self.mainWindow.statusBar.showMessage('File: <' + \
                                                   self.copySourceFileName + \
                                                   '> marked', 3000)

    def onPaste(self):
        if not self.index:
            return

        if not self.copySourceFilePath:
            self.mainWindow.statusBar.showMessage('nothing marked !', 3000)
            return

        if not self.copySourceFileName:
            self.mainWindow.statusBar.showMessage('nothing marked !', 3000)
            return

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        rootPath = os.getcwd()
        rootPath = self.checkPath(rootPath)
        fileList = os.listdir(self.path)  # File list at current path

        if fileName == '..':
            # clicked on '..'
            rootPath = os.getcwd()
            rootPath = self.checkPath(rootPath)

        if fileDir and self.isCopyFileFolder:
            # copy path to another path
            if fileName == '..':
                path = os.getcwd()
                path = self.checkPath(path)
            else:
                path = filePath

            newPath = path + '/' + self.copySourceFileName
            fileList = os.listdir(path)

            if self.copySourceFileName in fileList:
                q = MessageBox(
                    QMessageBox.Warning, "Error",
                    "Another path with the same name already exists.",
                    QMessageBox.NoButton)
                q.exec_()

                self.resetMarkedItems(True)
                return

            if self.copySourceFilePath in newPath:

                q = MessageBox(QMessageBox.Critical, 'Error',
                               'Name of path already exists in new path',
                               QMessageBox.NoButton)

                q.exec_()
                self.resetMarkedItems(True)
                return

            try:
                os.mkdir(newPath)
                self.copytree(self.copySourceFilePath, newPath)
                self.mainWindow.statusBar.showMessage('Done !', 3000)

            except Exception as e:
                q = MessageBox(QMessageBox.Critical, "Error", str(e),
                               QMessageBox.NoButton)
                q.exec_()

                self.resetMarkedItems(True)
                return

        elif fileDir and not self.isCopyFileFolder:
            # copy file to path
            if fileName == '..':
                path = os.getcwd()
                path = self.checkPath(path)
            else:
                path = filePath

            fileList = os.listdir(path)  # File list at current path

            if self.copySourceFileName in fileList:
                result = MessageBox(QMessageBox.Warning, "Warning",
                                    "File already exists.\n" + "Continue ?",
                                    QMessageBox.Yes | QMessageBox.No)

                if (result.exec_() == QMessageBox.Yes):

                    try:
                        shutil.copy(self.copySourceFilePath, path)
                        self.mainWindow.statusBar.showMessage('Done !', 3000)

                    except Exception as e:
                        q = MessageBox(QMessageBox.Critical, "Error", str(e),
                                       QMessageBox.NoButton)
                        q.exec_()

                        self.resetMarkedItems(True)
                        return
                else:
                    self.resetMarkedItems()
                    return
            else:

                try:
                    shutil.copy(self.copySourceFilePath, path)
                    self.mainWindow.statusBar.showMessage('Done !', 3000)

                except Exception as e:
                    q = MessageBox(QMessageBox.Critical, "Error", str(e),
                                   QMessageBox.NoButton)
                    q.exec_()

                    self.resetMarkedItems(True)
                    return

        elif not fileDir and self.isCopyFileFolder:
            # copy path to selected file -> correct this user input ...
            newPath = rootPath + '/' + self.copySourceFileName

            if self.copySourceFileName in fileList:
                q = MessageBox(
                    QMessageBox.Information, "Error",
                    "Another path with the same name already exists.",
                    QMessageBox.NoButton)
                q.exec_()

                self.resetMarkedItems(True)
                return

            try:
                os.mkdir(newPath)
                self.copytree(self.copySourceFilePath, newPath)
                self.mainWindow.statusBar.showMessage('Done !', 3000)

            except Exception as e:
                q = MessageBox(QMessageBox.Critical, "Error", str(e),
                               QMessageBox.NoButton)
                q.exec_()

                self.resetMarkedItems(True)
                return

        elif not fileDir and not self.isCopyFileFolder:
            # user copy file to another file -> correct this input
            fileList = os.listdir(rootPath)  # File list in current path

            if self.copySourceFileName in fileList:
                result = MessageBox(
                    QMessageBox.Warning, "Warning",
                    "File with this name already exists !" + "Continue ?",
                    QMessageBox.Yes | QMessageBox.No)

                if (result.exec_() == QMessageBox.Yes):

                    try:
                        shutil.copy(self.copySourceFilePath, rootPath)
                        self.mainWindow.statusBar.showMessage('Done !', 3000)

                    except Exception as e:
                        q = MessageBox(QMessageBox.Critical, "Error", str(e),
                                       QMessageBox.NoButton)
                        q.exec_()

                        self.resetMarkedItems(True)
                    return

                else:
                    self.resetMarkedItems(True)
                    return

            else:

                try:
                    shutil.copy(self.copySourceFilePath, rootPath)
                    self.mainWindow.statusBar.showMessage('Done !', 3000)

                except Exception as e:
                    q = MessageBox(QMessageBox.Critical, "Error", str(e),
                                   QMessageBox.Ok)
                    q.exec_()

                    self.resetMarkedItems(True)
                    return

        self.resetMarkedItems()

    def resetMarkedItems(self, showMessage=False):
        # reset marked items
        self.copySourceFilePath = None
        self.copySourceFileName = None
        self.isCopyFileFolder = None

        if showMessage:
            self.mainWindow.statusBar.showMessage('Mark removed !', 3000)

    # copy path with subfolder
    #  thanks to stackoverflow.com ..... !
    def copytree(self, src, dst, symlinks=False, ignore=None):
        if not os.path.exists(dst):
            os.makedirs(dst)
        if not os.path.exists(src):
            os.makedirs(src)

        for item in os.listdir(src):
            s = os.path.join(src, item)
            d = os.path.join(dst, item)

            if os.path.isdir(s):
                self.copytree(s, d, symlinks, ignore)
            else:
                if not os.path.exists(
                        d) or os.stat(s).st_mtime - os.stat(d).st_mtime > 1:
                    shutil.copy2(s, d)

    def onRename(self):
        if not self.index:
            return

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        dialog = EnterDialog(self.mainWindow, fileName, filePath, fileDir,
                             fileInfo, True)
        dialog.exec_()

    def onDelete(self):
        if not self.index:
            return

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        if fileDir:
            if fileName == '..':
                self.mainWindow.statusBar.showMessage(
                    'can not delete this item !', 3000)
                return
            else:
                result = MessageBox(QMessageBox.Warning, 'Delete directory',
                                    '<b>' + filePath + '</b>' + "  ?",
                                    QMessageBox.Yes | QMessageBox.No)

                if (result.exec_() == QMessageBox.Yes):
                    try:
                        shutil.rmtree(filePath)
                        self.mainWindow.statusBar.showMessage('Done !', 3000)
                        self.resetMarkedItems()

                    except Exception as e:
                        q = MessageBox(QMessageBox.Critical, "Error", str(e),
                                       QMessageBox.NoButton)
                        q.exec_()

                        self.resetMarkedItems(True)
                else:
                    return

        else:
            pathList = filePath.split('/')[:-1]
            path = ''
            for elem in pathList:
                path += elem + '/'
            file = filePath.split('/')[-1]
            result = MessageBox(QMessageBox.Warning, 'Delete file',
                                path + "<b>" + file + "</b>" + "  ?",
                                QMessageBox.Yes | QMessageBox.No)

            if (result.exec_() == QMessageBox.Yes):
                try:
                    os.remove(filePath)
                    self.mainWindow.statusBar.showMessage('Done !', 3000)
                except Exception as e:
                    q = MessageBox(QMessageBox.Critical, "Error", str(e),
                                   QMessageBox.NoButton)

                    q.exec_()

                    self.resetMarkedItems(True)

    def onTerminal(self):
        c = Configuration()
        system = c.getSystem()
        command = c.getTerminal(system)

        thread = RunThread(command)
        thread.start()

    def initItems(self):
        font = QFont()
        font.setPixelSize(16)

        self.prepareModel(os.getcwd())

        self.setToolTip(os.getcwd())

        # prepare drag and drop
        self.setDragEnabled(False)

        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        self.setSizePolicy(sizePolicy)
        self.setAutoExpandDelay(2)
        self.setAlternatingRowColors(False)
        self.setAnimated(False)
        self.setIndentation(20)
        self.setSortingEnabled(False)
        self.setRootIsDecorated(False)
        self.setPalette(QPalette(Qt.black))

        self.verticalScrollBar().setStyleSheet("""border: 20px solid black;
            background-color: darkgreen;
            alternate-background-color: #FFFFFF;""")

        self.horizontalScrollBar().setStyleSheet("""border: 20px solid black;
            background-color: darkgreen;
            alternate-background-color: #FFFFFF;""")

        self.setFont(font)

        # signals
        self.doubleClicked.connect(self.onDoubleClicked)
        self.clicked.connect(self.onClicked)
        self.pressed.connect(self.onClicked)
        #self.entered.connect(self.onEntered)
        self.columnMoved()

        # that hides the size, file type and last modified colomns
        self.setHeaderHidden(True)
        self.hideColumn(1)
        self.hideColumn(2)
        self.hideColumn(3)
        self.resize(400, 400)

    def prepareModel(self, path):
        self.model = QFileSystemModel()
        self.model.setRootPath(path)
        #model.setFilter(QDir.AllDirs |QDir.NoDotAndDotDot | QDir.AllEntries)
        self.model.setFilter(QDir.Files | QDir.AllDirs | QDir.NoDot
                             | QDir.Hidden)
        #self.model.setNameFilters(self.filter)

        self.model.rootPathChanged.connect(self.onRootPathChanged)

        self.fsindex = self.model.setRootPath(path)

        self.setModel(self.model)
        self.setRootIndex(self.fsindex)

    def checkPath(self, path):
        if '\\' in path:
            path = path.replace('\\', '/')
        return path

    def getFileInformation(self):
        index = self.index
        indexItem = self.model.index(index.row(), 0, index.parent())

        fileName = self.model.fileName(indexItem)
        filePath = self.model.filePath(indexItem)
        fileDir = self.model.isDir(indexItem)
        fileInfo = self.model.fileInfo(indexItem)

        fileName = self.checkPath(fileName)
        filePath = self.checkPath(filePath)

        return (fileName, filePath, fileDir, fileInfo)

    def onClicked(self, index):
        self.index = index  #.... index des FileSystemModels
        indexItem = self.model.index(index.row(), 0, index.parent())

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()
        self.setToolTip(filePath)

        if fileDir:
            self.path = self.checkPath(os.getcwd())
            self.filename = None
        else:
            self.filename = filePath
            self.path = self.checkPath(os.getcwd())

        #print('self.filename: ', self.filename)
        #print('self.path: ', self.path)

    def refresh(self, dir=None):
        if not dir:
            dir = self.checkPath(os.getcwd())
        else:
            dir = dir

        self.model.setRootPath(dir)

        if self.rootIsDecorated:
            self.setRootIsDecorated(False)

        self.clearSelection()

    def onDoubleClicked(self, index):
        self.index = index  #.... wie oben ... def onClicked(...):
        indexItem = self.model.index(index.row(), 0, index.parent())

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        if fileDir:
            filePath = self.checkPath(filePath)
            try:
                os.chdir(filePath)
            except Exception as e:
                self.mainWindow.statusBar.showMessage(str(e), 3000)
            self.path = self.checkPath(os.getcwd())

            self.model.setRootPath(filePath)

            if self.rootIsDecorated:
                self.setRootIsDecorated(False)

        else:
            self.filename = filePath

            try:
                with open(self.filename, 'r') as f:
                    self.text = f.read()
            except Exception as e:
                self.mainWindow.statusBar.showMessage(str(e), 3000)

                self.filename = None
                return

            # debug
            if self.textPad:

                if not self.textPad.filename:
                    editor = CodeEditor(self.mainWindow)
                    editor.setText(self.text)
                    editor.filename = filePath
                    self.notebook.newTab(editor)
                    self.textPad = editor

                    x = self.notebook.count()  # number of tabs
                    index = x - 1
                    self.notebook.setCurrentIndex(index)
                    tabName = os.path.basename(editor.filename)

                    self.notebook.setTabText(x, tabName)
                    self.textPad = editor
                    #self.textPad.filename = filePath

                else:
                    editor = CodeEditor(self.mainWindow)
                    editor.setText(self.text)
                    editor.filename = filePath
                    tabName = os.path.basename(editor.filename)
                    self.notebook.newTab(editor)
                    x = self.notebook.count()  # number of tabs
                    index = x - 1
                    self.notebook.setCurrentIndex(index)
                    self.textPad = editor
                    #self.textPad.filename = filePath

            if not self.textPad:
                editor = CodeEditor(self.mainWindow)
                editor.filename = None
                self.notebook.newTab(editor)
                x = self.notebook.count()
                index = x - 1
                self.notebook.setCurrentIndex(index)
                self.textPad = editor
                #self.textPad.filename = filePath

            # make codeView
            codeViewList = self.codeView.makeDictForCodeView(self.text)
            self.codeView.updateCodeView(codeViewList)

            # update textPad Autocomplete
            autocomplete = Qsci.QsciAPIs(self.textPad.lexer)
            self.textPad.autocomplete = autocomplete
            self.textPad.setPythonAutocomplete()

        self.clearSelection()

    def onRootPathChanged(self):
        self.setModel(None)
        self.setModel(self.model)
        self.fsindex = self.model.setRootPath(QDir.currentPath())
        self.setRootIndex(self.fsindex)
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        self.setSizePolicy(sizePolicy)
        self.setAutoExpandDelay(2)
        self.setAlternatingRowColors(False)
        self.setAnimated(True)
        self.setIndentation(20)
        self.setSortingEnabled(False)
        self.setRootIsDecorated(False)

        self.setHeaderHidden(True)
        self.hideColumn(1)
        self.hideColumn(2)
        self.hideColumn(3)
        self.setToolTip(QDir.currentPath())
        self.path = os.getcwd()
        self.path = self.checkPath(self.path)
Exemple #11
0
class MainUI(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi('interface.ui', self)
        self.zss = ZSSMain('zss.db')

        # Адресная строка
        self.button_path.clicked.connect(self.change_path)

        # Дерево файлов
        self.model_file = QFileSystemModel()
        self.model_file.setRootPath('')
        self.tree_file.setModel(self.model_file)

        self.tree_file.clicked.connect(self.tree_file_click)
        self.tree_file.doubleClicked.connect(self.tree_file_dclick)
        self.tree_file.customContextMenuRequested.connect(
            self.tree_file_rclick)
        self.tree_file.setContextMenuPolicy(Qt.CustomContextMenu)

        # Контекстное меню дерева файлов
        self.cmenu_tree_file = QMenu()
        self.cmenu_tree_file.addAction(self.rmenu_open)
        self.cmenu_tree_file.addAction(self.rmenu_delete)
        self.submenu_tree_file = QMenu()
        self.submenu_tree_file.setTitle("Добавить в БД")
        self.submenu_tree_file.addAction(self.new_doc)
        self.submenu_tree_file.addAction(self.new_img)
        self.cmenu_tree_file.addMenu(self.submenu_tree_file)

        # Привязка действий дерева файлов к функциям
        self.rmenu_open.triggered.connect(self.action_file_open)
        self.rmenu_delete.triggered.connect(self.action_file_del)
        self.new_doc.triggered.connect(self.action_new_doc)

        # Таблица атрибутов
        self.model_attr = QStandardItemModel()
        self.table_file.setModel(self.model_attr)

    def change_path(self):  # Переход по ссылке в адресной строке
        index = self.model_file.index(self.line_path.text())
        self.tree_file.setCurrentIndex(index)
        self.tree_file.setExpanded(index, True)
        self.tree_file.scrollTo(index)

    def tree_file_click(self, index):  # Выделение объекта в дереве файлов
        info = self.model_file.fileInfo(index)
        record_dict = ZSSRecord(info).getDict()
        print(record_dict)
        self.model_attr = QStandardItemModel()
        for item in record_dict.items():
            row = [QStandardItem(item[0]), QStandardItem(item[1])]
            print(item, row)
            self.model_attr.appendRow(row)
        self.table_file.setModel(self.model_attr)
        self.table_file.resizeColumnsToContents()

    def tree_file_dclick(self, index):  # Двойной клик объекта в дереве файлов
        info = self.model_file.fileInfo(index)
        record_dict = ZSSRecord(info).getDict()
        if record_dict['isFile']:
            self.action_file_open()

    def tree_file_rclick(self,
                         position):  # Правый клик объекта в дереве файлов
        self.cmenu_tree_file.exec_(
            self.tree_file.viewport().mapToGlobal(position))

    # Дерево файлов - действия
    def action_file_open(self):
        index = self.tree_file.currentIndex()
        path = self.model_file.filePath(index)
        try:
            os.startfile(path)
        except:
            print('Не удалось открыть объект')

    def action_file_del(self):
        index = self.tree_file.currentIndex()
        path = self.model_file.filePath(index)
        try:
            shutil.rmtree(path)
        except:
            try:
                os.remove(path)
            except:
                print('Не удалось удалить объект')

    def action_new_doc(self):
        index = self.tree_file.currentIndex()
        path = self.model_file.filePath(index)
        info = self.model_file.fileInfo(index)
        record = ZSSRecordDocument(info)
        self.zss.new_doc(record.getDict())
Exemple #12
0
class FileManager(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self)
        self.parent = parent
        self.name = 'File Manager'
        self.port = '9080'
        self.server = None

        drives = win32api.GetLogicalDriveStrings().split('\\\000')[:-1]
        self.logical_drives = drives + [d+'/' for d in drives]
        # create file manager tab
        self.file_manager_layout = QGridLayout(self)

        # create left manager (PC)
        self.left_up_btn = QPushButton()
        self.left_up_btn.setIcon(QIcon('images/up_btn.png'))
        self.left_up_btn.setFixedWidth(25)
        self.file_manager_layout.addWidget(self.left_up_btn, 0, 0, 1, 1)

        self.left_dir_path = QLineEdit(self.parent.expanduser_dir)
        self.file_manager_layout.addWidget(self.left_dir_path, 0, 1, 1, 8)

        self.left_go_to_btn = QPushButton()
        self.left_go_to_btn.setIcon(QIcon('images/right_btn.png'))
        self.left_go_to_btn.setFixedWidth(25)
        self.file_manager_layout.addWidget(self.left_go_to_btn, 0, 9, 1, 1)

        self.lefttableview = QTableView()
        self.lefttableview.setSelectionBehavior(QTableView.SelectRows)
        self.lefttableview.verticalHeader().hide()
        self.lefttableview.setShowGrid(False)
        self.lefttableview.contextMenuEvent = lambda event: self.left_context(event)

        self.left_file_model = QFileSystemModel()
        self.left_file_model.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.left_file_model.setRootPath(self.parent.expanduser_dir)
        self.left_file_model_path = self.parent.expanduser_dir
        self.lefttableview.setModel(self.left_file_model)
        self.lefttableview.setColumnWidth(0, 150)
        self.lefttableview.setRootIndex(self.left_file_model.index(self.parent.expanduser_dir))
        self.file_manager_layout.addWidget(self.lefttableview, 1, 0, 5, 10)

        # central buttons
        self.download_file_from_device_btn = QPushButton()
        self.download_file_from_device_btn.setIcon(QIcon('images/left_btn.png'))
        self.download_file_from_device_btn.setFixedWidth(30)
        self.download_file_from_device_btn.setEnabled(False)
        self.upload_file_to_device_btn = QPushButton()
        self.upload_file_to_device_btn.setIcon(QIcon('images/right_btn.png'))
        self.upload_file_to_device_btn.setFixedWidth(30)
        self.upload_file_to_device_btn.setEnabled(False)
        self.delete_file_btn = QPushButton()
        self.delete_file_btn.setIcon(QIcon('images/delete_btn.png'))
        self.delete_file_btn.setFixedWidth(30)
        self.file_manager_layout.addWidget(self.download_file_from_device_btn, 3, 10, 1, 1)
        self.file_manager_layout.addWidget(self.delete_file_btn, 4, 10, 1, 1)

        # create right manager (Device)
        self.right_up_btn = QPushButton()
        self.right_up_btn.setIcon(QIcon('images/up_btn.png'))
        self.right_up_btn.setFixedWidth(25)
        self.right_up_btn.setEnabled(False)
        self.file_manager_layout.addWidget(self.right_up_btn, 0, 11, 1, 1)

        self.add_folder_btn = QPushButton()
        self.add_folder_btn.setIcon(QIcon('images/folder_add.png'))
        self.add_folder_btn.setFixedWidth(25)
        self.add_folder_btn.setToolTip(_('Add new folder'))
        self.add_folder_btn.setEnabled(False)
        self.file_manager_layout.addWidget(self.add_folder_btn, 0, 12, 1, 1)

        self.right_dir_path = QLineEdit()
        self.file_manager_layout.addWidget(self.right_dir_path, 0, 13, 1, 7)

        self.right_update_btn = QPushButton()
        self.right_update_btn.setIcon(QIcon('images/update.png'))
        self.right_update_btn.setFixedWidth(25)
        self.file_manager_layout.addWidget(self.right_update_btn, 0, 20, 1, 1)

        self.righttableview = QTableView()
        self.righttableview.setSelectionBehavior(QTableView.SelectRows)
        self.righttableview.contextMenuEvent = lambda event: self.right_context(event)
        self.righttableview.verticalHeader().hide()
        self.righttableview.setShowGrid(False)
        self.right_file_model = QStandardItemModel()
        self.right_file_model_path = []
        self.right_active_dir = None
        self.righttableview.setModel(self.right_file_model)
        self.file_manager_layout.addWidget(self.righttableview, 1, 11, 5, 10)

        # auto sync
        self.timer = QTimer()
        self.timer.setInterval(10000)
        self.file_models_auto_sync = QCheckBox(_('Auto sync'))
        self.left_file_model_auto_sync_label = QLineEdit()
        self.left_file_model_auto_sync_label.setReadOnly(True)
        self.right_file_model_auto_sync_label = QLineEdit()
        self.right_file_model_auto_sync_label.setReadOnly(True)
        self.file_manager_layout.addWidget(self.file_models_auto_sync, 6, 9, 1, 3, alignment=Qt.AlignCenter)
        self.file_manager_layout.addWidget(self.left_file_model_auto_sync_label, 6, 0, 1, 9)
        self.file_manager_layout.addWidget(self.right_file_model_auto_sync_label, 6, 12, 1, 9)

        self.timer.timeout.connect(lambda: self.check_device_sync())
        self.lefttableview.clicked.connect(lambda idx: self.left_file_model_clicked(idx))
        self.lefttableview.doubleClicked.connect(lambda idx: self.left_file_model_doubleclicked(idx))
        self.left_up_btn.clicked.connect(lambda: self.left_file_model_up(self.left_file_model.index(self.left_dir_path.text())))
        self.left_go_to_btn.clicked.connect(lambda: self.left_file_model_go_to_dir())

        self.right_update_btn.clicked.connect(lambda: self.right_file_model_update())
        self.righttableview.doubleClicked.connect(lambda idx: self.right_file_model_doubleclicked(idx))
        self.right_up_btn.clicked.connect(lambda: self.right_file_model_up())
        self.add_folder_btn.clicked.connect(lambda: self.right_file_model_add_folder())
        self.righttableview.clicked.connect(lambda idx: self.right_file_model_clicked(idx))
        self.download_file_from_device_btn.clicked.connect(lambda: self.download_file_from_device())
        self.upload_file_to_device_btn.clicked.connect(lambda: self.upload_file_to_device())
        self.delete_file_btn.clicked.connect(lambda: self.delete_file_from_file_model())

        self.parent.settings_widget.signal_ip_changed.connect(lambda ip: self.change_ip(ip))

        self.parent.signal_language_changed.connect(lambda: self.retranslate())

    def retranslate(self):
        self.file_models_auto_sync.setText(_('Auto sync'))
        self.right_file_model.setHorizontalHeaderLabels([_('Name'), _('Size'), _('Changed date')])

    def change_ip(self, ip):
        self.server = ':'.join([ip, self.port])
        self.right_file_model_path = []
        self.right_file_model.clear()

    def left_file_model_clicked(self, idx):
        if os.path.isfile(self.left_file_model.filePath(idx)) and self.parent.geoshark_widget.device_on_connect:
            self.upload_file_to_device_btn.setEnabled(True)
        else:
            self.upload_file_to_device_btn.setEnabled(False)

    def left_file_model_doubleclicked(self, idx):
        self.left_up_btn.setEnabled(True)
        fileinfo = self.left_file_model.fileInfo(idx)
        if fileinfo.isDir():
            self.lefttableview.setRootIndex(idx)
            self.left_dir_path.setText(self.left_file_model.filePath(idx))
            self.left_file_model_path = self.left_file_model.filePath(idx)

    def left_file_model_up(self, idx):
        self.upload_file_to_device_btn.setEnabled(False)
        if self.left_dir_path.text() in self.logical_drives:
            self.left_file_model = QFileSystemModel()
            self.left_file_model.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
            self.left_file_model.setRootPath('')
            self.lefttableview.setModel(self.left_file_model)
            self.left_dir_path.setText('My computer')
            self.left_up_btn.setEnabled(False)
        else:
            fileinfo = self.left_file_model.fileInfo(idx)
            dir = fileinfo.dir()
            self.left_dir_path.setText(dir.path())
            self.left_file_model_path = dir.path()
            self.lefttableview.setRootIndex(self.left_file_model.index(dir.absolutePath()))

    def left_file_model_go_to_dir(self):
        if os.path.isdir(self.left_dir_path.text()):
            self.left_file_model_path = self.left_dir_path.text()
            self.left_up_btn.setEnabled(True)
            self.upload_file_to_device_btn.setEnabled(False)
            self.left_file_model.setRootPath(self.left_dir_path.text())
            self.lefttableview.setRootIndex(self.left_file_model.index(self.left_dir_path.text()))

    def right_file_model_update(self):
        if not self.parent.geoshark_widget.device_on_connect:
            return
        url = 'http://{}/active_dir'.format(self.server)
        try:
            res = requests.get(url, timeout=5)
            if res.ok:
                self.right_active_dir = res.text
        except requests.exceptions.RequestException:
            pass

        file_list = self.get_folder_list()
        if file_list is None:
            return
        self.fill_right_file_model(file_list)
        self.download_file_from_device_btn.setEnabled(False)

    def get_folder_list(self, folder_path=None):
        if self.server is None:
            return
        if folder_path is None:
            folder_path = '/'.join(self.right_file_model_path)
        url = 'http://{}/data/{}'.format(self.server, folder_path)
        try:
            res = requests.get(url, timeout=1)
        except requests.exceptions.RequestException:
            show_error(_('GeoShark error'), _('GeoShark is not responding.'))
            return
        if res.ok:
            res = res.json()
            return res
        else:
            return None

    def check_device_sync(self):
        pc_path = self.left_file_model_auto_sync_label.text()
        device_path = self.right_file_model_auto_sync_label.text()
        if self.file_models_auto_sync.isChecked() and pc_path != '' and device_path != '':
            file_list = self.get_folder_list(self.right_file_model_auto_sync_label.text())
            left_list_of_files = os.listdir(self.left_file_model_auto_sync_label.text())
            for f in file_list:
                if f['name'] not in left_list_of_files or os.path.getsize('{}/{}'.format(pc_path, f['name'])) != f['size']:
                    self.download_file_from_device(device_path='{}/{}'.format(device_path, f['name']),
                                                   pc_path=pc_path)

    def fill_right_file_model(self, directory):
        self.add_folder_btn.setEnabled(True)
        if len(self.right_file_model_path) < 1:
            self.right_up_btn.setEnabled(False)
        else:
            self.right_up_btn.setEnabled(True)
            self.add_folder_btn.setEnabled(False)
        self.right_file_model.removeRows(0, self.right_file_model.rowCount())
        self.right_dir_path.setText('/'.join(self.right_file_model_path))
        self.right_file_model.setHorizontalHeaderLabels([_('Name'), _('Size'), _('Changed date')])
        for row, instance in enumerate(directory):
            if instance['name'] == self.right_active_dir:
                image = QIcon('images/directory_active.png')
            else:
                image = QIcon('images/{}.png'.format(instance['type']))
            item = QStandardItem(image, instance['name'])
            item.setData(instance['type'], 5)
            item.setEditable(False)
            self.right_file_model.setItem(row, 0, item)
            item = QStandardItem(str(instance['size']))
            item.setEditable(False)
            self.right_file_model.setItem(row, 1, item)
            item = QStandardItem(str(datetime.datetime.fromtimestamp(instance['changed']).strftime('%d.%m.%Y %H:%M')))
            item.setEditable(False)
            self.right_file_model.setItem(row, 2, item)

        self.righttableview.setColumnWidth(0, max(150, self.righttableview.columnWidth(0)))

    def left_context(self, event):
        context_menu = {}
        index = self.lefttableview.indexAt(event.pos())
        if index.row() == -1:
            return
        context_menu[_('Set active directory')] = lambda: self.set_pc_active_directory(self.left_file_model.filePath(index))
        context_menu[_('Remove element')] = lambda: self.delete_file_from_file_model(index)

        if not self.left_file_model.isDir(index):
            del context_menu[_('Set active directory')]

        menu = QMenu()

        actions = [QAction(a) for a in context_menu.keys()]
        menu.addActions(actions)
        action = menu.exec_(event.globalPos())
        if action:
            context_menu[action.text()]()

    def set_pc_active_directory(self, path):
        self.left_file_model_auto_sync_label.setText(path)
        self.parent.settings_widget.left_folder_tracked.setText(path)

    def right_context(self, event):
        context_menu = {}

        index = self.righttableview.indexAt(event.pos())
        if index.row() == -1:
            return
        item = self.right_file_model.itemFromIndex(index)
        item_row = item.row()

        context_menu[_('Set active directory')] = lambda: self.set_active_directory(item)
        context_menu[_('Remove element')] = lambda: self.delete_file_from_file_model(index)

        if self.right_file_model.item(item_row, 0).data(5) != 'directory':
            del context_menu[_('Set active directory')]

        menu = QMenu()

        actions = [QAction(a) for a in context_menu.keys()]
        menu.addActions(actions)
        action = menu.exec_(event.globalPos())
        if action:
            context_menu[action.text()]()

    def set_active_directory(self, item):
        if not self.parent.geoshark_widget.device_on_connect:
            return
        dirname = item.text()
        url = 'http://{}/active_dir'.format(self.server)
        try:
            res = requests.post(url=url, data=dirname, timeout=5)
        except requests.exceptions.RequestException:
            show_error(_('GeoShark error'), _('Can not set active directory.\nGeoShark is not responding.'))
            return
        if res.ok:
            self.right_file_model_update()
            self.set_active_path(dirname)
        elif res.status_code == 400:
            show_error(_('GeoShark error'), _('Request declined - request body specifies invalid path.'))
            return
        elif res.status_code == 409:
            show_error(_('GeoShark error'), _('Request declined - switching active directory is forbidden during active session.'))
            return
        else:
            print(res.status_code)
            return

    def set_active_path(self, dirname):
        path = '/'.join(self.right_file_model_path + [dirname])
        self.parent.settings_widget.right_folder_tracked.setText(path)
        self.right_file_model_auto_sync_label.setText(path)

    def right_file_model_clicked(self, idx):
        if not self.parent.geoshark_widget.device_on_connect:
            return
        if self.right_file_model.item(idx.row(), 0).data(5) == 'file':
            self.download_file_from_device_btn.setEnabled(True)
        else:
            self.download_file_from_device_btn.setEnabled(False)

    def right_file_model_doubleclicked(self, idx):
        if not self.parent.geoshark_widget.device_on_connect:
            return
        model_path = '/'.join(self.right_file_model_path)
        idx_name = self.right_file_model.item(idx.row(), 0).text()
        if model_path != '':
            dir = '{}/{}'.format(model_path, idx_name)
        else:
            dir = '{}'.format(idx_name)

        file_list = self.get_folder_list(dir)
        if file_list is None:
            return
        self.right_file_model_path = dir.split('/')
        self.fill_right_file_model(file_list)

    def right_file_model_up(self):
        if not self.parent.geoshark_widget.device_on_connect:
            return
        self.download_file_from_device_btn.setEnabled(False)
        up_dir = '/'.join(self.right_file_model_path[:-1])

        file_list = self.get_folder_list(up_dir)
        if file_list is None:
            return
        if up_dir == '':
            self.right_file_model_path = []
        else:
            self.right_file_model_path = up_dir.split('/')
        self.fill_right_file_model(file_list)

    def right_file_model_add_folder(self):
        if not self.parent.geoshark_widget.device_on_connect:
            return
        row = self.right_file_model.rowCount()
        item = QStandardItem(QIcon('images/folder.png'), 'New Directory')
        item.setData('directory', 5)
        item.setEditable(True)
        self.right_file_model.setItem(row, 0, item)
        item = QStandardItem(str(0.0))
        item.setEditable(False)
        self.right_file_model.setItem(row, 1, item)
        item = QStandardItem(str(datetime.datetime.today().strftime('%d.%m.%Y %H:%M')))
        item.setEditable(False)
        self.right_file_model.setItem(row, 2, item)

    def download_file_from_device(self, device_path=None, pc_path=None):
        if not self.parent.geoshark_widget.device_on_connect or self.server is None:
            return

        if not device_path:
            fileName = self.find_selected_idx()
            if fileName:
                fileName = fileName.data()
                device_path = '/'.join(self.right_file_model_path + [fileName])
            else:
                return

        right_file_model_filename = device_path.split('/')[-1]
        save_to_file = '{}/{}'.format(self.left_file_model_path, right_file_model_filename) \
            if not pc_path else '{}/{}'.format(pc_path, right_file_model_filename)
        if os.path.isfile(save_to_file):
            answer = show_warning_yes_no(_('File warning'), _('There is a file with the same name in PC.\n'
                                         'Do you want to rewrite <b>{}</b>?'.format(right_file_model_filename)))
            if answer == QMessageBox.No:
                return
        url = 'http://{}/data/{}'.format(self.server, device_path)
        try:
            b = bytearray()
            res = requests.get(url, timeout=5, stream=True)
            if res.ok:
                progress = QProgressBar()
                progress.setFormat(right_file_model_filename)
                self.file_manager_layout.addWidget(progress, 6, 12, 1, 9)
                total_length = int(res.headers.get('content-length'))
                len_b = 0
                for chunk in tee_to_bytearray(res, b):
                    len_b += len(chunk)
                    progress.setValue((len_b/total_length)*99)
                    QApplication.processEvents()
            else:
                return
        except:
            self.file_manager_layout.addWidget(self.right_file_model_auto_sync_label, 6, 12, 1, 9)
            show_error(_('GeoShark error'), _('GeoShark is not responding.'))
            return

        if res.ok:
            progress.setValue(100)

            with open(save_to_file, 'wb') as file:
                file.write(b)
        for i in reversed(range(self.file_manager_layout.count())):
            if isinstance(self.file_manager_layout.itemAt(i).widget(), QProgressBar):
                self.file_manager_layout.itemAt(i).widget().setParent(None)
        self.file_manager_layout.addWidget(self.right_file_model_auto_sync_label, 6, 12, 1, 9)

    def upload_file_to_device(self):
        if not self.parent.geoshark_widget.device_on_connect or self.server is None:
            return
        file = self.left_file_model.filePath(self.lefttableview.currentIndex())
        filename = file.split('/')[-1]
        url = 'http://{}/data/{}'.format(self.server, '/'.join(self.right_file_model_path))
        filesize = os.path.getsize(file)
        if filesize == 0:
            show_error(_('File error'), _('File size must be non zero.'))
            return
        progress = ProgressBar(text=_('Upload File Into GeoShark'), window_title=_('Upload file to GeoShark'))
        encoder = MultipartEncoder(
            fields={'upload_file': (filename, open(file, 'rb'))}  # added mime-type here
        )
        data = MultipartEncoderMonitor(encoder, lambda monitor: progress.update((monitor.bytes_read/filesize)*99))

        try:
            res = requests.post(url, data=data, headers={'Content-Type': encoder.content_type}, timeout=5)
        except requests.exceptions.RequestException:
            progress.close()
            show_error(_('GeoShark error'), _('GeoShark is not responding.'))
            return
        if res.ok:
            progress.update(100)
            self.right_file_model_update()

    def delete_file_from_file_model(self, index=None):
        selected = self.find_selected_idx()
        if index is None and selected is None:
            return
        if index is None:
            index = selected
        model = index.model()
        index_row = index.row()
        path = model.filePath(index) if hasattr(model, 'filePath') else model.index(index_row, 0).data()
        answer = show_warning_yes_no(_('Remove File warning'),
                                     _('Do you really want to remove:\n{}').format(path))
        if answer == QMessageBox.No:
            return

        if isinstance(model, QFileSystemModel):
            model.remove(index)

        elif isinstance(model, QStandardItemModel):
            if not self.parent.geoshark_widget.device_on_connect or self.server is None:
                return
            filename = self.right_file_model.item(index.row(), 0).text()
            path = '/'.join(self.right_file_model_path + [filename])

            url = 'http://{}/data/{}'.format(self.server, path)
            try:
                res = requests.delete(url)
            except requests.exceptions.RequestException:
                show_error(_('GeoShark error'), _('GeoShark is not responding.'))
                return
            if res.ok:
                self.right_file_model_update()
            elif res.status_code == 400:
                self.right_file_model.removeRow(index.row())
            elif res.status_code == 409:
                show_error(_('GeoShark error'),
                           _('Request declined - directory is the part of active session working directory.'))
                return

    def find_selected_idx(self):
        left_indexes = self.lefttableview.selectedIndexes()
        right_indexes = self.righttableview.selectedIndexes()
        if len(left_indexes) == 0 and len(right_indexes) == 0:
            return None
        index = left_indexes[0] if len(left_indexes) > len(right_indexes) else right_indexes[0]
        return index

    def save_file_models_folder(self):
        self.left_file_model_auto_sync_label.setText(self.parent.settings_widget.left_folder_tracked.text())
        self.right_file_model_auto_sync_label.setText(self.parent.settings_widget.right_folder_tracked.text())
Exemple #13
0
class Dialog_ImageFolder():
    def __init__(self, parent, title, init_path):
        self.w = QDialog(parent)

        self.parent = parent
        self.left = 300
        self.top = 300
        self.width = 600
        self.height = 400
        self.title = title

        self.dirModel = QFileSystemModel()
        self.dirModel.setRootPath(init_path)
        self.dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)
        self.treeview = QTreeView()
        self.treeview.setModel(self.dirModel)
        self.treeview.setRootIndex(self.dirModel.index(""))
        self.treeview.clicked.connect(self.on_clicked)
        #--- Hide All Header Sections Except First ----
        header = self.treeview.header()
        for sec in range(1, header.count()):
            header.setSectionHidden(sec, True)
        #--- ---- ---- ---- ---- ---- ---- ---- ---- --

        focus_index = self.dirModel.index(init_path)
        self.treeview.setCurrentIndex(focus_index)
        self.current_row_changed()

        self.listview = QListView()
        self.listview.setViewMode(QListView.IconMode)
        self.listview.setIconSize(QSize(192, 192))

        targetfiles1 = glob.glob(os.path.join(init_path, '*.png'))
        targetfiles2 = glob.glob(os.path.join(init_path, '*.tif'))
        targetfiles3 = glob.glob(os.path.join(init_path, '*.tiff'))
        targetfiles = targetfiles1 + targetfiles2 + targetfiles3
        lm = _MyListModel(targetfiles, self.parent)
        self.listview.setModel(lm)

        self.sub_layout = QHBoxLayout()
        self.sub_layout.addWidget(self.treeview)
        self.sub_layout.addWidget(self.listview)

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Open
                                          | QDialogButtonBox.Cancel)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

        self.main_layout = QVBoxLayout()
        self.main_layout.addLayout(self.sub_layout)
        self.main_layout.addWidget(self.buttonBox)

        self.w.setGeometry(self.left, self.top, self.width, self.height)
        self.w.setWindowTitle(self.title)
        self.w.setWindowIcon(QIcon(os.path.join(icon_dir, 'Mojo2_16.png')))
        self.w.setLayout(self.main_layout)

    def current_row_changed(self):
        index = self.treeview.currentIndex()
        self.treeview.scrollTo(index, QAbstractItemView.EnsureVisible)
        self.treeview.resizeColumnToContents(0)

    def on_clicked(self, index):
        path = self.dirModel.fileInfo(index).absoluteFilePath()

        targetfiles1 = glob.glob(os.path.join(path, '*.png'))
        targetfiles2 = glob.glob(os.path.join(path, '*.tif'))
        targetfiles3 = glob.glob(os.path.join(path, '*.tiff'))
        targetfiles = targetfiles1 + targetfiles2 + targetfiles3

        lm = _MyListModel(targetfiles, self.parent)
        self.listview.setModel(lm)

    def accept(self):
        index = self.treeview.currentIndex()
        self.newdir = self.dirModel.filePath(index)
        self.w.done(1)

    def reject(self):
        self.w.done(0)

    def GetValue(self):
        index = self.treeview.currentIndex()
        self.newdir = self.dirModel.filePath(index)
        return self.newdir
Exemple #14
0
class FileManager(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(FileManager, self).__init__(parent)
        self.title = 'PyQt5 file system view - pythonspot.com'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.default_path = (os.path.join(os.path.expanduser('~'), 'linuxcnc/nc_files/examples'))
        self.user_path = (os.path.join('/media'))
        self.currentPath = None
        self.EXT = INFO.PROGRAM_FILTERS_EXTENSIONS
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files)
        self.model.setNameFilterDisables(False)
        self.model.setNameFilters(self.EXT)

        self.list = QListView()
        self.list.setModel(self.model)
        self.updateDirectoryView(self.default_path)
        self.list.setWindowTitle("Dir View")
        self.list.resize(640, 480)
        self.list.clicked[QModelIndex].connect(self.clicked)
        self.list.activated.connect(self._getPathActivated)
        #self.list.currentChanged = self.currentChanged
        self.list.setAlternatingRowColors(True)

        self.cb = QComboBox()
        self.cb.currentTextChanged.connect(self.filterChanged)
        self.cb.addItems(self.EXT)
        #self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.button = QPushButton()
        self.button.setText('Media')
        self.button.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button.setToolTip('Jump to Media directory')
        self.button.clicked.connect(self.onMediaClicked)

        self.button2 = QPushButton()
        self.button2.setText('User')
        self.button2.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button2.setToolTip('Jump to linuxcnc directory')
        self.button2.clicked.connect(self.onUserClicked)

        hbox = QHBoxLayout()
        hbox.addWidget(self.button)
        hbox.addWidget(self.button2)
        hbox.addWidget(self.cb)

        windowLayout = QVBoxLayout()
        windowLayout.addWidget(self.list)
        windowLayout.addLayout(hbox)
        self.setLayout(windowLayout)
        self.show()

    # this could return the current/previous selected as it's selected.
    # need to uncomment monkey patch of self.list.currentChanged above
    # so far this is not needed
    def currentChanged(self,c,p):
        dir_path = self.model.filePath(c)
        print('-> ',dir_path)

    def updateDirectoryView(self, path):
        self.list.setRootIndex(self.model.setRootPath(path))

    def filterChanged(self, text):
        self.model.setNameFilters([text])

    def clicked(self, index):
        # the signal passes the index of the clicked item
        dir_path = self.model.filePath(index)
        if self.model.fileInfo(index).isFile():
            self.currentPath = dir_path
            return
        root_index = self.model.setRootPath(dir_path)
        self.list.setRootIndex(root_index)

    def onMediaClicked(self):
        self.updateDirectoryView(self.user_path)

    def onUserClicked(self):
        self.updateDirectoryView(self.default_path)

    def select_row(self, style):
        style = style.lower()
        selectionModel = self.list.selectionModel()
        row = selectionModel.currentIndex().row()
        self.rows = self.model.rowCount(self.list.rootIndex())

        if style == 'last':
            row = self.rows
        elif style == 'up':
            if row > 0:
                row -= 1
            else:
                row = 0
        elif style == 'down':
            if row < self.rows:
                row += 1
            else:
                row = self.rows
        else:
            return
        top = self.model.index(row, 0, self.list.rootIndex())
        selectionModel.setCurrentIndex(top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    # returns the current highlighted (selected) path as well as
    # whether it's a file or not.
    def getCurrentSelected(self):
        selectionModel = self.list.selectionModel()
        index = selectionModel.currentIndex()
        dir_path = self.model.filePath(index)
        if self.model.fileInfo(index).isFile():
            return (dir_path, True)
        else:
            return (dir_path, False)

    def _hal_init(self):
        if self.PREFS_:
            last_path = self.PREFS_.getpref('last_loaded_directory', self.default_path, str, 'BOOK_KEEPING')
            self.updateDirectoryView(last_path)
            LOG.debug("lAST FILE PATH: {}".format(last_path))
        else:
            LOG.debug("lAST FILE PATH: {}".format(self.default_path))
            self.updateDirectoryView(self.default_path)

    # get current selection and update the path
    # then if the path is good load it into linuxcnc
    # record it in the preference file if available
    def _getPathActivated(self):
        row = self.list.selectionModel().currentIndex()
        self.clicked(row)

        fname = self.currentPath
        if fname is None: 
            return
        if fname:
            self.load(fname)

    # this can be class patched to do something else
    def load(self, fname=None):
        if fname is None:
            self._getPathActivated()
            return
        self.recordBookKeeping()
        ACTION.OPEN_PROGRAM(fname)
        STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME')

    # this can be class patched to do something else
    def recordBookKeeping(self):
        fname = self.currentPath
        if fname is None: 
            return
        if self.PREFS_:
            self.PREFS_.putpref('last_loaded_directory', self.model.rootPath(), str, 'BOOK_KEEPING')
            self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING')

    # moves the selection up
    # used with MPG scrolling
    def up(self):
        self.select_row('up')

    # moves the selection down
    # used with MPG scrolling
    def down(self):
        self.select_row('down')
Exemple #15
0
class FileManager(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(FileManager, self).__init__(parent)
        self.title = 'Qtvcp File System View'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.media_path = (os.path.join(os.path.expanduser('~'),
                                        'linuxcnc/nc_files'))
        user = os.path.split(os.path.expanduser('~'))[-1]
        self.user_path = (os.path.join('/media', user))
        self.currentPath = None
        self.currentFolder = None
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        pasteBox = QHBoxLayout()
        self.textLine = QLineEdit()
        self.textLine.setToolTip('Current Director/selected File')
        self.pasteButton = QToolButton()
        self.pasteButton.setEnabled(False)
        self.pasteButton.setText('Paste')
        self.pasteButton.setToolTip(
            'Copy file from copy path to current directory/file')
        self.pasteButton.clicked.connect(self.paste)
        self.pasteButton.hide()
        pasteBox.addWidget(self.textLine)
        pasteBox.addWidget(self.pasteButton)

        self.copyBox = QFrame()
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        self.copyLine = QLineEdit()
        self.copyLine.setToolTip('File path to copy from, when pasting')
        self.copyButton = QToolButton()
        self.copyButton.setText('Copy')
        self.copyButton.setToolTip('Record current file as copy path')
        self.copyButton.clicked.connect(self.recordCopyPath)
        hbox.addWidget(self.copyButton)
        hbox.addWidget(self.copyLine)
        self.copyBox.setLayout(hbox)
        self.copyBox.hide()

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files)
        self.model.setNameFilterDisables(False)
        self.model.rootPathChanged.connect(self.folderChanged)

        self.list = QListView()
        self.list.setModel(self.model)
        self.updateDirectoryView(self.media_path)
        self.list.resize(640, 480)
        self.list.clicked[QModelIndex].connect(self.listClicked)
        self.list.activated.connect(self._getPathActivated)
        self.list.setAlternatingRowColors(True)

        self.cb = QComboBox()
        self.cb.currentIndexChanged.connect(self.filterChanged)
        self.fillCombobox(INFO.PROGRAM_FILTERS_EXTENSIONS)
        self.cb.setMinimumHeight(30)
        self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,
                                          QSizePolicy.Fixed))

        self.button2 = QToolButton()
        self.button2.setText('Media')
        self.button2.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button2.setMinimumSize(60, 30)
        self.button2.setToolTip('Jump to Media directory')
        self.button2.clicked.connect(self.onJumpClicked)

        SettingMenu = QMenu(self)
        self.settingMenu = SettingMenu
        for i in ('Media', 'User'):
            axisButton = QAction(QIcon.fromTheme('user-home'), i, self)
            # weird lambda i=i to work around 'function closure'
            axisButton.triggered.connect(
                lambda state, i=i: self.jumpTriggered(i))
            SettingMenu.addAction(axisButton)
        self.button2.setMenu(SettingMenu)

        self.button3 = QToolButton()
        self.button3.setText('Add Jump')
        self.button3.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button3.setMinimumSize(60, 30)
        self.button3.setToolTip('Add current directory to jump button list')
        self.button3.clicked.connect(self.onActionClicked)

        hbox = QHBoxLayout()
        hbox.addWidget(self.button2)
        hbox.addWidget(self.button3)
        hbox.insertStretch(2, stretch=0)
        hbox.addWidget(self.cb)

        windowLayout = QVBoxLayout()
        windowLayout.addLayout(pasteBox)
        windowLayout.addWidget(self.copyBox)
        windowLayout.addWidget(self.list)
        windowLayout.addLayout(hbox)
        self.setLayout(windowLayout)
        self.show()

    def _hal_init(self):
        if self.PREFS_:
            last_path = self.PREFS_.getpref('last_loaded_directory',
                                            self.media_path, str,
                                            'BOOK_KEEPING')
            self.updateDirectoryView(last_path)
            LOG.debug("lAST FILE PATH: {}".format(last_path))
        else:
            LOG.debug("lAST FILE PATH: {}".format(self.media_path))
            self.updateDirectoryView(self.media_path)

    #########################
    # callbacks
    #########################

    # add shown text and hidden filter data from the INI
    def fillCombobox(self, data):
        for i in data:
            self.cb.addItem(i[0], i[1])

    def folderChanged(self, data):
        self.currentFolder = data
        self.textLine.setText(data)

    def updateDirectoryView(self, path):
        self.list.setRootIndex(self.model.setRootPath(path))

    # retrieve selected filter (it's held as QT.userData)
    def filterChanged(self, index):
        userdata = self.cb.itemData(index)
        self.model.setNameFilters(userdata)

    def listClicked(self, index):
        # the signal passes the index of the clicked item
        dir_path = self.model.filePath(index)
        if self.model.fileInfo(index).isFile():
            self.currentPath = dir_path
            self.textLine.setText(self.currentPath)
            return
        root_index = self.model.setRootPath(dir_path)
        self.list.setRootIndex(root_index)

    def onUserClicked(self):
        self.showUserDir()

    def onMediaClicked(self):
        self.showMediaDir()

    def onJumpClicked(self):
        data = self.button2.text()
        if data == 'Media':
            self.showMediaDir()
        elif data == 'User':
            self.showUserDir()
        else:
            self.updateDirectoryView(self.button2.text())

    def jumpTriggered(self, data):
        if data == 'Media':
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip('Jump to Media directory')
            self.showMediaDir()
        elif data == 'User':
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip('Jump to User directory')
            self.showUserDir()
        else:
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip('Jump to directory: {}'.format(data))
            self.updateDirectoryView(self.button2.text())

    def onActionClicked(self):
        i = self.currentFolder
        button = QAction(QIcon.fromTheme('user-home'), i, self)
        # weird lambda i=i to work around 'function closure'
        button.triggered.connect(lambda state, i=i: self.jumpTriggered(i))
        self.settingMenu.addAction(button)

    # get current selection and update the path
    # then if the path is good load it into linuxcnc
    # record it in the preference file if available
    def _getPathActivated(self):
        row = self.list.selectionModel().currentIndex()
        self.listClicked(row)

        fname = self.currentPath
        if fname is None:
            return
        if fname:
            self.load(fname)

    def recordCopyPath(self):
        data, isFile = self.getCurrentSelected()
        if isFile:
            self.copyLine.setText(os.path.normpath(data))
            self.pasteButton.setEnabled(True)
        else:
            self.copyLine.setText('')
            self.pasteButton.setEnabled(False)
            STATUS.emit('error', OPERATOR_ERROR,
                        'Can only copy a file, not a folder')

    def paste(self):
        res = self.copyFile(self.copyLine.text(), self.textLine.text())
        if res:
            self.copyLine.setText('')
            self.pasteButton.setEnabled(False)

    ########################
    # helper functions
    ########################

    def showCopyControls(self, state):
        if state:
            self.copyBox.show()
            self.pasteButton.show()
        else:
            self.copyBox.hide()
            self.pasteButton.hide()

    def showMediaDir(self):
        self.updateDirectoryView(self.user_path)

    def showUserDir(self):
        self.updateDirectoryView(self.media_path)

    def copyFile(self, s, d):
        try:
            shutil.copy(s, d)
            return True
        except Exception as e:
            LOG.error("Copy file error: {}".format(e))
            STATUS.emit('error', OPERATOR_ERROR,
                        "Copy file error: {}".format(e))
            return False

    # moves the selection up
    # used with MPG scrolling
    def up(self):
        self.select_row('up')

    # moves the selection down
    # used with MPG scrolling
    def down(self):
        self.select_row('down')

    def select_row(self, style='down'):
        style = style.lower()
        selectionModel = self.list.selectionModel()
        row = selectionModel.currentIndex().row()
        self.rows = self.model.rowCount(self.list.rootIndex())

        if style == 'last':
            row = self.rows
        elif style == 'up':
            if row > 0:
                row -= 1
            else:
                row = 0
        elif style == 'down':
            if row < self.rows:
                row += 1
            else:
                row = self.rows
        else:
            return
        top = self.model.index(row, 0, self.list.rootIndex())
        selectionModel.setCurrentIndex(
            top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    # returns the current highlighted (selected) path as well as
    # whether it's a file or not.
    def getCurrentSelected(self):
        selectionModel = self.list.selectionModel()
        index = selectionModel.currentIndex()
        dir_path = self.model.filePath(index)
        if self.model.fileInfo(index).isFile():
            return (dir_path, True)
        else:
            return (dir_path, False)

    # This can be class patched to do something else
    def load(self, fname=None):
        if fname is None:
            self._getPathActivated()
            return
        self.recordBookKeeping()
        ACTION.OPEN_PROGRAM(fname)
        STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME')

    # This can be class patched to do something else
    def recordBookKeeping(self):
        fname = self.currentPath
        if fname is None:
            return
        if self.PREFS_:
            self.PREFS_.putpref('last_loaded_directory', self.model.rootPath(),
                                str, 'BOOK_KEEPING')
            self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING')
Exemple #16
0
class MainWin(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWin,self).__init__()
        self.setupUi(self)
        self.Login.triggered.connect(self.open_login)
        self.RGB.triggered.connect(self.open_image_rgb)
        self.LoginDialog = LoginDialog()
        self.ImageMainWin = ImageRGB()

        # 设置TreeWidgets
        self.trees = [self.YCPGAMETREE, self.YCPCOMPTREE, self.YLANDFILETREE]
        for tree in self.trees:
            tree.setContextMenuPolicy(Qt.CustomContextMenu)
            tree.customContextMenuRequested.connect(self.show_context_menu)
            tree.header().setMinimumSectionSize(120)

        self.model = QFileSystemModel()

        self.RailID = ''
        self.ylands_path = ''
        self.rail_user_data = ''
        self.ycp_game_folder_path = ''
        self.ycp_comp_folder_path = ''
        self.yland_folder_path = ''
        self.key = OpenKey(HKEY_CURRENT_USER, r"Software\Rail\YlandsRail")
        _value, type = QueryValueEx(self.key, "InstallPath")
        if _value:
            self.ylands_path = _value
            self.rail_user_data = Path.dirname(self.ylands_path) + '\\' + 'rail_user_data\\2000108'
        self.YCPTAB.currentChanged.connect(self.refresh_tab_qlistwidget)
        self.GroupBoxTitleDict = {0: 'YCP游戏目录', 1: 'YCP组件目录', 2: 'YLAND文件目录'}
        self.YCPTAB.setCurrentIndex(0)
        print(self.OpenDirBtn.clicked)

    # 打开workshop 后去RailId
    def open_login(self):
        self.LoginDialog.LoginRailIDSignel.connect(self.slot_emit)
        self.LoginDialog.show()

    def open_image_rgb(self):
        self.ImageMainWin.show()

    def slot_emit(self, flag, str):
        # 获得 rail_id
        self.RailID = str
        self.ycp_game_folder_path = self.rail_user_data + '\\' + self.RailID + '\\cloud_storage\\files\\Share\\Games'
        self.ycp_comp_folder_path = self.rail_user_data + '\\' + self.RailID + '\\cloud_storage\\files\\Share\\Compositions'
        self.yland_folder_path = self.rail_user_data + '\\' + self.RailID + '\\cloud_storage\\files\\Scenarios'
        if not Path.exists(self.ycp_game_folder_path):
            makedirs(self.ycp_game_folder_path)
        if not Path.exists(self.ycp_comp_folder_path):
            makedirs(self.ycp_comp_folder_path)
        if not Path.exists(self.yland_folder_path):
            makedirs(self.yland_folder_path)
        self.YCPTAB.setEnabled(True)
        self.YCPTAB.setCurrentIndex(0)
        self.refresh_tab_qlistwidget(0)
        self.setAcceptDrops(True)

    def refresh_tab_qlistwidget(self, index):
        if self.RailID != '':
            self.OpenDirBtn.setEnabled(True)
            if index == 0:
                self.YCPGAMETREE.setEnabled(True)
                self.refresh_path(index, self.ycp_game_folder_path)
                self.model.setRootPath(self.ycp_game_folder_path)
                self.YCPGAMETREE.setModel(self.model)
                self.YCPGAMETREE.setRootIndex(self.model.index(self.ycp_game_folder_path))

            elif index == 1:
                self.YCPCOMPTREE.setEnabled(True)
                self.refresh_path(index, self.ycp_comp_folder_path)
                self.model.setRootPath(self.ycp_comp_folder_path)
                self.YCPCOMPTREE.setModel(self.model)
                self.YCPCOMPTREE.setRootIndex(self.model.index(self.ycp_comp_folder_path))
            else:
                self.YLANDFILETREE.setEnabled(True)
                self.refresh_path(index, self.yland_folder_path)
                self.model.setRootPath(self.yland_folder_path)
                self.YLANDFILETREE.setModel(self.model)
                self.YLANDFILETREE.setRootIndex(self.model.index(self.yland_folder_path))

    def refresh_path(self, index, path):
        self.files_count(path)
        self.frame.findChild(QGroupBox, 'groupBox').setTitle(self.GroupBoxTitleDict[index])
        self.PathTxt.setText(path)
        if MainWin.isconnected(self.OpenDirBtn, 'clicked()'):
            self.OpenDirBtn.disconnect()
        self.OpenDirBtn.clicked.connect(lambda: self.open_dir(path, index))
        #TODO 通过背景颜色,显示文件被使用的状态

    def open_dir(self, path, index):
        # QFileDialog.getExistingDirectory(self,"浏览"+ self.GroupBoxTitleDict[index], path, QFileDialog.ShowDirsOnly)
        QFileDialog.getOpenFileNames(self, "浏览" + self.GroupBoxTitleDict[index], path, "All Files (*);;Text Files (*.txt)")

    def files_count(self, path):
        count = 0
        for root, dirs, files in walk(path):
            for each in files:
                file = Path.splitext(each)
                filename, type = file
                if type != '.txt':
                    count += 1
        self.statusbar.showMessage("文件数:" + str(count))

    @staticmethod
    def isconnected(obj, name):
        """判断信号是否连接
        :param obj:        对象
        :param name:       信号名,如 clicked()
        """
        index = obj.metaObject().indexOfMethod(name)
        if index > -1:
            method = obj.metaObject().method(index)
            if method:
                return obj.isSignalConnected(method)
        return False

    def show_context_menu(self, pos):
        sender = self.sender()
        row_index = sender.indexAt(pos).row()
        menu = QMenu()
        cpy = menu.addAction('复制')
        cpy.triggered.connect(lambda: self.copy_selected(sender.currentIndex()))
        rmfile = menu.addAction('删除')
        rmfile.triggered.connect(lambda: self.remove_selected_file(sender.currentIndex()))
        menu.exec_(QCursor.pos())

    def copy_selected(self, index):
        filename = self.model.fileName(index)
        filepath = self.model.filePath(index)
        data = QMimeData()
        url = QUrl.fromLocalFile(filepath)
        clipboard = QApplication.clipboard()
        data.setUrls([url])
        clipboard.setMimeData(data)

    def remove_selected_file(self, index):
        filename = self.model.fileName(index)
        filepath = self.model.filePath(index)
        if not self.model.fileInfo(index).isDir():
            msgBox = QMessageBox()
            msgBox.setText("确定删除文件:" + filename + "?")
            msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
            ret = msgBox.exec_()
            if ret == QMessageBox.Ok:
                self.model.remove(index)
            else:
                return

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls:
            filetempname = event.mimeData().urls()[0].fileName()
            filename, extension = Path.splitext(filetempname)
            if self.YCPTAB.currentIndex() == 0 or self.YCPTAB.currentIndex() == 1:
                if extension == '.ycp':
                    event.accept()
                    # clipboard = QApplication.clipboard()
                    # clipboard.clear()
                    # clipboard.setMimeData(event.mimeData())
                else:
                    msgBox = QMessageBox()
                    msgBox.setText("只能拖放.ycp后缀文件")
                    ret = msgBox.exec_()
                    event.ignore()
                    return
            elif self.YCPTAB.currentIndex() == 2:
                if extension == '.yland':
                    event.accept()
                    # clipboard = QApplication.clipboard()
                    # clipboard.clear()
                    # clipboard.setMimeData(event.mimeData())
                else:
                    msgBox = QMessageBox()
                    msgBox.setText("只能拖放.yland后缀文件")
                    ret = msgBox.exec_()
                    event.ignore()
                    return

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls:
            try:
                event.setDropAction(Qt.CopyAction)
            except Exception as e:
                print(e)
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        try:
            if event.mimeData().hasUrls:
                event.setDropAction(Qt.CopyAction)
                event.accept()
                filepath = event.mimeData().urls()[0]
                filename = filepath.fileName()
                if self.YCPTAB.currentIndex() == 0:
                    self.copy_file(filepath.url().replace("file:///", ""), Path.join(self.ycp_game_folder_path, filename))
                elif self.YCPTAB.currentIndex() == 1:
                    self.copy_file(filepath.url().replace("file:///", ""), Path.join(self.ycp_comp_folder_path, filename))
                else:
                    self.copy_file(filepath.url().replace("file:///", ""), Path.join(self.yland_folder_path, filename))
            else:
                event.ignore()
        except Exception as e:
            print(e)

    def copy_file(self,srcfle, dstfile):
        newdstfile = dstfile
        if not Path.isfile(srcfle):
            print("$%s not exist!" % (srcfle))
        else:
            fpath, ftempname = Path.split(dstfile)
            if not Path.exists(fpath):
                makedirs(fpath)
            elif Path.exists(dstfile):
                filename, extension = Path.splitext(ftempname)
                newdstfile = Path.join(fpath, filename + "copybyylandsbox" + extension)
            copyfile(srcfle, newdstfile)
Exemple #17
0
    class App(QWidget):
        def __init__(self):
            super().__init__()
            self.left = 100
            self.top = 100
            self.width = 1200
            self.height = 720
            self.setWindowTitle('Mammogram Prediction')
            self.setGeometry(self.left, self.top, self.width, self.height)

            self.initUI()

        def initUI(self):
            # Widget for showing picture. The QLabel gets a Pixmap added to it to show picture
            self.picture_name_label = QLabel(currently_selected_picture)
            self.picture_label = QLabel()
            self.prediction_text = QTextEdit()
            self.prediction_text.setReadOnly(True)
            self.model_label = QLabel()

            self.init_picture_and_predictions()

            self.resized_picture = self.picture.scaled(299, 299,
                                                       Qt.KeepAspectRatio,
                                                       Qt.FastTransformation)
            self.picture_label.setPixmap(self.resized_picture)
            self.picture_label.setMinimumWidth(299)
            self.picture_label.setMinimumHeight(299)
            self.picture_label.setContentsMargins(0, 19, 0, 0)

            # Tree and List view for file directory overview of pictures
            self.picture_directory_label = QLabel('Select a Picture:')
            picture_dir_path = 'pictures\\'
            picture_file_path = 'pictures\\'
            self.treeview_picture = QTreeView()
            self.listview_picture = QListView()

            self.dirModel_picture = QFileSystemModel()
            self.dirModel_picture.setRootPath(picture_dir_path)
            self.dirModel_picture.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)

            self.fileModel_picture = QFileSystemModel()
            self.fileModel_picture.setRootPath(picture_file_path)  #
            self.fileModel_picture.setFilter(QDir.NoDotAndDotDot | QDir.Files)

            self.treeview_picture.setModel(self.dirModel_picture)
            self.listview_picture.setModel(self.fileModel_picture)

            self.treeview_picture.setRootIndex(
                self.dirModel_picture.index(picture_dir_path))
            self.listview_picture.setRootIndex(
                self.fileModel_picture.index(picture_file_path))  #
            self.treeview_picture.setCurrentIndex(
                self.dirModel_picture.index(0, 0))

            self.treeview_picture.clicked.connect(
                self.on_picture_treeview_clicked)
            self.listview_picture.clicked.connect(
                self.on_picture_listview_clicked)
            self.treeview_picture.setColumnHidden(1, True)
            self.treeview_picture.setColumnWidth(0, 275)
            self.treeview_picture.setMinimumWidth(500)
            self.listview_picture.setMinimumWidth(500)

            # List view for file directory overview of five label models
            self.model_directory_label = QLabel('Select a Five Label Model:')
            model_path = 'trained_five_Models\\'
            self.listview_model = QListView()
            self.dirModel_model = QFileSystemModel()

            self.dirModel_model.setRootPath(model_path)
            self.dirModel_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)

            self.listview_model.setModel(self.dirModel_model)
            self.listview_model.setRootIndex(
                self.dirModel_model.index(model_path))
            self.listview_model.clicked.connect(self.on_model_listview_clicked)

            # List view for file directory overview of binary models
            self.model_binary_directory_label = QLabel(
                'Select a Binary Model:')
            model_binary_path = 'trained_binary_Models\\'
            self.listview_model_binary = QListView()
            self.dirModel_model_binary = QFileSystemModel()

            self.dirModel_model_binary.setRootPath(model_binary_path)
            self.dirModel_model_binary.setFilter(QDir.NoDotAndDotDot
                                                 | QDir.AllDirs)

            self.listview_model_binary.setModel(self.dirModel_model_binary)
            self.listview_model_binary.setRootIndex(
                self.dirModel_model_binary.index(model_binary_path))
            self.listview_model_binary.setSelectionMode(
                QAbstractItemView.MultiSelection)
            self.listview_model_binary.clicked.connect(
                self.on_model_binary_listview_clicked)

            # Layout handling.

            # self.gridlayout = QGridLayout()
            # self.gridlayout.addWidget(self.model_directory_label, 0, 0)
            # self.gridlayout.setColumnStretch(-15, -11)
            # self.gridlayout.addWidget(self.listview_model, 1, 0)
            # self.gridlayout.addWidget(self.picture_directory_label, 2, 0)
            # self.gridlayout.addWidget(self.treeview_picture, 3, 0)
            #
            # self.gridlayout.addWidget(self.model_binary_directory_label, 0, 1)
            # self.gridlayout.addWidget(self.listview_model_binary, 1, 1)
            # self.gridlayout.addWidget(self.listview_picture, 3, 1)
            #
            # self.gridlayout.addWidget(self.picture_label, 0, 2)
            # self.gridlayout.addWidget(self.picture_name_label, 1, 2)
            # self.gridlayout.addWidget(self.prediction_text, 3, 2)

            self.vbox = QVBoxLayout()
            self.vbox_left = QVBoxLayout()
            self.vbox_right = QVBoxLayout()
            self.hbox_outer = QHBoxLayout()
            self.hbox_top = QHBoxLayout()
            self.hbox_buttom = QHBoxLayout()
            self.vbox_five_label = QVBoxLayout()
            self.vbox_binary = QVBoxLayout()

            self.vbox.addLayout(self.hbox_outer)
            self.hbox_outer.addLayout(self.vbox_left)
            self.hbox_outer.addLayout(self.vbox_right)
            self.vbox_left.addLayout(self.hbox_top)
            self.hbox_top.addLayout(self.vbox_five_label)
            self.hbox_top.addLayout(self.vbox_binary)

            self.vbox_five_label.addWidget(self.model_directory_label)
            self.vbox_five_label.addWidget(self.listview_model)
            self.vbox_binary.addWidget(self.model_binary_directory_label)
            self.vbox_binary.addWidget(self.listview_model_binary)

            self.vbox_left.addWidget(self.picture_directory_label)
            self.vbox_left.addLayout(self.hbox_buttom)
            self.hbox_buttom.addWidget(self.treeview_picture)
            self.hbox_buttom.addWidget(self.listview_picture)

            self.vbox_right.addWidget(self.picture_label,
                                      alignment=Qt.AlignHCenter)
            self.vbox_right.addWidget(self.picture_name_label,
                                      alignment=Qt.AlignHCenter)
            self.vbox_right.addWidget(self.model_label,
                                      alignment=Qt.AlignHCenter)
            self.vbox_right.addWidget(self.prediction_text)

            self.vbox_right.setAlignment(Qt.AlignCenter)

            self.setLayout(self.vbox)
            self.sizePolicy = QSizePolicy(QSizePolicy.Minimum,
                                          QSizePolicy.Preferred)
            self.setSizePolicy(self.sizePolicy)
            self.show()

        def init_picture_and_predictions(self):
            if currently_selected_picture == 'Currently No Image Selected':
                self.picture = QtGui.QPixmap('GUI/no_image_selected.png')
                self.prediction_text.setText('')

        def on_picture_treeview_clicked(self, index):
            pathof_selected_dir = self.dirModel_picture.fileInfo(
                index).absoluteFilePath()
            self.listview_picture.setRootIndex(
                self.fileModel_picture.setRootPath(pathof_selected_dir))

        def on_picture_listview_clicked(self, index):
            global currently_selected_model
            global currently_selected_model_name
            global currently_selected_picture

            currently_selected_picture = self.fileModel_picture.fileInfo(
                index).absoluteFilePath()

            try:
                Image.open(currently_selected_picture)
                self.picture_name_label.setText(currently_selected_picture)
                self.picture_label.setPixmap(
                    QtGui.QPixmap(currently_selected_picture))
            except IOError:
                print('Exception: Chosen file is not a picture')

            # Checks if the selected picture has size 299
            image_in = cv2.imread(currently_selected_picture)
            size = image_in.shape[:2]
            if size[0] == 299:
                if currently_selected_model is not None:
                    for model in currently_selected_model:
                        new_prediction = self.makePrediction(
                            model,
                            self.convertPictureToNumpy(
                                currently_selected_picture))
                        split = currently_selected_model_name.split('_')
                        if split[4] in ('neg', 'bc', 'bm', 'mc', 'mm'):
                            self.show_binary_prediction(
                                new_prediction, split[4])
                        else:
                            self.show_five_prediction(new_prediction)
                else:
                    self.prediction_text.setText(
                        'No Model is Chosen for Prediction. Choose one to the left.'
                    )
            # If the selected picture is not size 299 it will be padded and cropped
            else:
                cropped_images = resize_image_padding(
                    currently_selected_picture)
                self.listview_picture.setRootIndex(
                    self.fileModel_picture.setRootPath('pictures/cropped/%s' %
                                                       cropped_images))

        def on_model_listview_clicked(self, index):
            global currently_selected_model
            global currently_selected_picture

            currently_selected_model = []

            selected_model_path = self.dirModel_model.fileInfo(
                index).absoluteFilePath()
            currently_selected_model.append(self.getModel(selected_model_path))

            self.model_label.setText(currently_selected_model_name[0])

            if currently_selected_picture != 'Currently No Image Selected':
                for model in currently_selected_model:
                    new_prediction = self.makePrediction(
                        model,
                        self.convertPictureToNumpy(currently_selected_picture))
                    self.show_five_prediction(new_prediction)

        def on_model_binary_listview_clicked(self):
            global currently_selected_model
            global currently_selected_picture
            currently_selected_model = []

            self.prediction_text.setText('')
            self.model_label.setText('')

            for x in self.listview_model_binary.selectedIndexes():
                selected_model_path = self.dirModel_model_binary.fileInfo(
                    x).absoluteFilePath()
                currently_selected_model.append(
                    self.getModel(selected_model_path))
            # if not currently_selected_model_name:
            #     self.model_label.setText(currently_selected_model_name)

            if currently_selected_picture != 'Currently No Image Selected':
                for y in currently_selected_model:
                    new_prediction = self.makePrediction(
                        y,
                        self.convertPictureToNumpy(currently_selected_picture))
                    self.show_binary_prediction(new_prediction, y.category)

        def getModel(self, model_path):
            global currently_selected_model_name
            currently_selected_model_name = []

            split = os.path.split(model_path)[1].split('_')
            model_version = split[0] + '_' + split[1] + '_' + split[
                2] + '_' + split[3]
            currently_selected_model_name.append(os.path.split(model_path)[1])

            model = getattr(sys.modules[__name__], model_version)()
            checkpoint_path = model_path + '/cp.ckpt'
            model.load_weights(checkpoint_path)
            return model

        def makePrediction(self, input_model, input_picture):
            image = tf.reshape(input_picture, [-1, 299, 299, 1])
            image = tf.cast(image, tf.float32)
            image = image / 255.0
            return input_model.predict(image)

        def convertPictureToNumpy(self, filename):
            img = Image.open(filename)
            np_array = np.array(img, dtype='uint8')
            return np_array

        def show_five_prediction(self, prediction):
            self.prediction_text.setText(
                "Probability of Negative: %s" % prediction[0, 0] +
                "\n\nProbability of Benign Calcification: %s" %
                prediction[0, 1] +
                "\n\nProbability of Benign Mass: %s" % prediction[0, 2] +
                "\n\nProbability of Malignant Calcification: %s" %
                prediction[0, 3] +
                "\n\nProbability of Malignant Mass: %s" % prediction[0, 4])

        def show_binary_prediction(self, prediction, category):
            if category == 'neg':
                self.prediction_text.append(
                    "Probability of Negative: %s %s \n" %
                    (prediction[0, 0], prediction[0, 1]))
            elif category == 'bc':
                self.prediction_text.append(
                    "Probability of Benign Calcification:  %s %s \n" %
                    (prediction[0, 0], prediction[0, 1]))
            elif category == 'bm':
                self.prediction_text.append(
                    "Probability of Benign Mass: %s %s \n" %
                    (prediction[0, 0], prediction[0, 1]))
            elif category == 'mc':
                self.prediction_text.append(
                    "Probability of Malignant Calcification: %s %s \n" %
                    (prediction[0, 0], prediction[0, 1]))
            elif category == 'mm':
                self.prediction_text.append(
                    "Probability of Malignant Mass: %s %s \n" %
                    (prediction[0, 0], prediction[0, 1]))
            else:
                self.prediction_text.append(
                    "Probability of ????: %s %s \n" %
                    (prediction[0, 0], prediction[0, 1]))

        def openFileDialog(self):
            fileName, _ = QFileDialog.getOpenFileName(
                self, "QFileDialog.getOpenFileName()", "",
                "All Files (*);;Python Files (*.py)")
            if fileName:
                return fileName

        def is_png(data):
            return data[:8] == '\x89PNG\x0d\x0a\x1a\x0a'
Exemple #18
0
class TextRenamer(QtWidgets.QMainWindow):
    ui = None

    currentFullNames = None
    currentExtensions = None
    path = None
    currentIndex = None

    showExtension = False

    def __init__(self):

        # init user interface:
        super(TextRenamer, self).__init__()
        self.show()
        self.ui = uic.loadUi('textRenamer.ui', self)

        # TODO: remember last used path
        self.path = QDir.rootPath()

        # Set up files and folder views
        self.foldersModel = QFileSystemModel()
        self.foldersModel.setRootPath(self.path)
        self.foldersModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)

        self.filesModel = QFileSystemModel()
        self.filesModel.setFilter(QDir.NoDotAndDotDot | QDir.Files)

        self.ui.folderView.setModel(self.foldersModel)
        self.ui.filesView.setModel(self.filesModel)

        # Remove all columns but the folder name
        self.ui.folderView.setRootIndex(self.foldersModel.index(self.path))
        self.ui.folderView.hideColumn(1)
        self.ui.folderView.hideColumn(2)
        self.ui.folderView.hideColumn(3)

        # Set path for start
        self.ui.filesView.setRootIndex(self.filesModel.index(self.path))

        # Event handlers:
        self.ui.renameButton.clicked.connect(self.renameFiles)
        self.ui.folderView.clicked.connect(self.openFolder)
        self.filesModel.directoryLoaded.connect(self.loadedFolder)
        self.ui.extensionCheckbox.stateChanged.connect(
            self.extensionCheckboxChanged)

    def extensionCheckboxChanged(self, state):
        if state == 0:
            self.showExtension = False
        else:
            self.showExtension = True
        self.readCurrentNames()

    def loadedFolder(self, path):
        # Delay reading to get correct file order
        QTimer.singleShot(1, self.readCurrentNames)

    def readCurrentNames(self):
        # Reset
        self.currentFullNames = []

        for i in range(self.filesModel.rowCount(self.currentIndex)):
            self.currentFullNames.append(self.currentIndex.child(i, 0).data())

        self.currentNames = [
            os.path.splitext(x)[0] for x in self.currentFullNames
        ]
        self.currentExtensions = [
            os.path.splitext(x)[1] for x in self.currentFullNames
        ]

        if self.showExtension:
            fileListText = '\n'.join(self.currentFullNames)
        else:
            fileListText = '\n'.join(self.currentNames)

        self.ui.newText.setPlainText(fileListText)

        # Only enable the rename button once everything is loaded
        self.ui.renameButton.setEnabled(True)

    def openFolder(self, index):
        self.path = self.foldersModel.fileInfo(index).absoluteFilePath()
        self.currentIndex = self.filesModel.setRootPath(self.path)
        self.ui.filesView.setRootIndex(self.currentIndex)
        # Clear info text
        self.ui.errorLabel.setText("")

    def renameFiles(self):
        # Read new names (only use as many rows as we have currentFullNames):
        newNames = self.ui.newText.toPlainText().split(
            '\n')[:len(self.currentFullNames)]

        if self.showExtension:
            self.newFullNames = newNames
        else:
            # Add extension
            self.newFullNames = [
                i + j for i, j in zip(newNames, self.currentExtensions)
            ]

        # TODO: Add temporary filenames for cases where a new name conflicts with a name that has not yet been renamed

        # Sanity checkes:
        enoughNames = False
        allNamesHaveCharacters = False
        allNamesUnique = False

        # Sanity check: All new names have characters
        if len(self.newFullNames) >= len(self.currentFullNames):
            enoughNames = True
        else:
            self.ui.errorLabel.setText("Error: Not enough names given")

        # Sanity chcek: All names have characters
        allNamesHaveCharacters = True
        for newName in self.newFullNames:
            if newName == "":
                allNamesHaveCharacters = False
                self.ui.errorLabel.setText("Error: Blank new name")
                break

        # Sanity chcek: All names unique
        if self.allUnique(self.newFullNames):
            allNamesUnique = True
        else:
            self.ui.errorLabel.setText("Error: All names have to be unique")

        renamedCount = 0
        notChangedCount = 0
        errorCount = 0
        # Rename
        if enoughNames and allNamesHaveCharacters and allNamesUnique:
            for currentName, newName in zip(self.currentFullNames,
                                            self.newFullNames):
                print(self.path + "/" + currentName + " > " + newName)

                # Dont rename needlessly
                if not currentName == newName:
                    currentFile = os.path.join(self.path, currentName).replace(
                        os.sep, '/')
                    newFileName = os.path.join(self.path,
                                               newName).replace(os.sep, '/')
                    # Only rename if the current file exists
                    if os.path.exists(currentFile):
                        renamedOk = QtCore.QFile.rename(
                            currentFile, newFileName)
                        if not renamedOk:
                            errorCount += 1
                        renamedCount += 1
                    else:
                        notChangedCoint += 1
                else:
                    notChangedCount += 1
            labelText = "Renamed: " + str(renamedCount) + " files"
            if notChangedCount > 0:
                labelText += ", No change: " + str(notChangedCount)
            if errorCount > 0:
                labelText += ", Error: " + str(errorCount)

            # Set info text
            self.ui.errorLabel.setText(labelText)

    # Early exit uniqueness checker, returns true if all items in x are unique
    def allUnique(self, x):
        seen = set()
        return not any(i in seen or seen.add(i) for i in x)
Exemple #19
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        self.filename = "untitled"
        self.temptab="NewTest.C"
        self.changesSaved = True
        self._process = []
        self.num=21
        self.out12=""
        MainWindow.setObjectName("MainWindow")
        MainWindow.closeEvent = self.closeEvent
        MainWindow.resize(1279, 724)
        MainWindow.setAcceptDrops(False)
        MainWindow.setAutoFillBackground(False)
        MainWindow.setStyleSheet("background-color: #31363b;color: white;padding-left: 0.4ex;spacing: 0.2ex;border: 0.1ex dashed #76797c;")
        MainWindow.showMaximized()
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.centralwidget)
        self.horizontalLayout_3.setContentsMargins(1, 1, 4, 0)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.splitter_2 = QtWidgets.QSplitter(self.centralwidget)
        self.splitter_2.setOrientation(QtCore.Qt.Horizontal)
        self.splitter_2.setHandleWidth(10)
        self.splitter_2.setObjectName("splitter_2")
        self.splitter_2.setStyleSheet("background-color: #232629;")
        #Tree View
        self.treeView = QtWidgets.QTreeView(self.splitter_2)
        path = QDir.rootPath()
        self.dirModel = QFileSystemModel()
        self.dirModel.setRootPath(QDir.rootPath())
        self.dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)
        self.fileModel = QFileSystemModel()
        self.fileModel.setFilter(QDir.NoDotAndDotDot |  QDir.Files)
        self.model = QtWidgets.QFileSystemModel()
        self.model.setRootPath((QtCore.QDir.rootPath()))
        self.treeView.setModel(self.model)
        self.treeView.setRootIndex(self.dirModel.index(path))
        self.treeView.clicked.connect(self.on_clicked)
        self.treeView.setGeometry(QtCore.QRect(0, 0, 270, 921))
        self.treeView.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;")
        self.treeView.setObjectName("treeView")
        self.treeView.hideColumn(1)
        self.treeView.hideColumn(2)
        self.treeView.hideColumn(3)

        #Tree View 
        self.splitter = QtWidgets.QSplitter(self.splitter_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.splitter.sizePolicy().hasHeightForWidth())
        self.splitter.setSizePolicy(sizePolicy)
        self.splitter.setOrientation(QtCore.Qt.Vertical)
        self.splitter.setHandleWidth(10)
        self.splitter.setObjectName("splitter")
        self.splitter.setStyleSheet("background-color: #232629;")
        self.frame = QtWidgets.QFrame(self.splitter)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(2)
        sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
        self.frame.setSizePolicy(sizePolicy)
        self.frame.setStyleSheet("background-color: #232629;")
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setSpacing(0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.tabWidget_2 = QtWidgets.QTabWidget(self.frame)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.tabWidget_2.sizePolicy().hasHeightForWidth())
        self.tabWidget_2.setSizePolicy(sizePolicy)
        self.tabWidget_2.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;")
        self.tabWidget_2.setObjectName("tabWidget_2")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.tab)
        self.verticalLayout_7.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_7.setSpacing(0)
        self.verticalLayout_7.setObjectName("verticalLayout_7")
        self.plainTextEdit=LineNumber_dark.QCodeEditor(self.tab)
        self.highlighter=hightest_dark.Highlighter(self.plainTextEdit.document())
        self.plainTextEdit.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;")
        self.plainTextEdit.setObjectName("plainTextEdit")
        self.plainTextEdit.textChanged.connect(self.changed)
        self.verticalLayout_7.addWidget(self.plainTextEdit)
        self.tabWidget_2.addTab(self.tab, "")
        self.horizontalLayout.addWidget(self.tabWidget_2)
        self.frame_3 = QtWidgets.QFrame(self.splitter)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(2)
        sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth())

        self.frame_3.setSizePolicy(sizePolicy)
        self.frame_3.setStyleSheet("background-color: #232629;")
        self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_3.setObjectName("frame_3")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_3)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setSpacing(0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.tabWidget = QtWidgets.QTabWidget(self.frame_3)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth())
        self.tabWidget.setSizePolicy(sizePolicy)
        self.tabWidget.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;")
        self.tabWidget.setTabShape(QtWidgets.QTabWidget.Rounded)
        self.tabWidget.setObjectName("tabWidget")
        
        self.tab1 = QTermWidget()
        self.tab1.setScrollBarPosition(self.tab1.ScrollBarRight)
        
        self.tab1.setColorScheme("WhiteOnBlack")
        self.tabWidget.addTab(self.tab1, "Terminal")
        
        self.tab_3 = QtWidgets.QWidget()
        self.tab_3.setObjectName("tab_3")
        self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.tab_3)
        self.verticalLayout_7.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_7.setSpacing(0)
        self.verticalLayout_7.setObjectName("verticalLayout_7")
        self.plainTextEdit23=QtWidgets.QPlainTextEdit(self.tab_3)
        self.plainTextEdit23.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;")
        self.plainTextEdit23.setObjectName("plainTextEdit23")
        self.verticalLayout_7.addWidget(self.plainTextEdit23)
        self.tabWidget.addTab(self.tab_3, "")
        self.horizontalLayout_2.addWidget(self.tabWidget)
        self.horizontalLayout_3.addWidget(self.splitter_2)
        self.verticalLayout_6 = QtWidgets.QVBoxLayout()
        self.verticalLayout_6.setObjectName("verticalLayout_6")
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_3.setFont(font)
        self.label_3.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.label_3.setStyleSheet("background-color:  #008000;\n"
"color: rgb(255, 255, 255);\n"
"border-top-left-radius: 18px;\n"
"border-top-right-radius: 18px;\n"
"text-align: center;")
        self.label_3.setTextFormat(QtCore.Qt.AutoText)
        self.label_3.setAlignment(QtCore.Qt.AlignCenter)
        self.label_3.setWordWrap(False)
        self.label_3.setObjectName("label_3")
        self.verticalLayout.addWidget(self.label_3)
        self.plainTextEdit_2 = QtWidgets.QPlainTextEdit(self.centralwidget)
        self.plainTextEdit_2.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;")
        self.plainTextEdit_2.setObjectName("plainTextEdit_2")
        self.verticalLayout.addWidget(self.plainTextEdit_2)
        self.verticalLayout.setStretch(0, 1)
        self.verticalLayout.setStretch(1, 8)
        self.verticalLayout_6.addLayout(self.verticalLayout)
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setSpacing(0)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_2.setFont(font)
        self.label_2.setStyleSheet("background-color:  #008000;\n"
"color: rgb(255, 255, 255);\n"
"border-top-left-radius: 18px;\n"
"border-top-right-radius: 18px;\n"
"text-align: center;")
        self.label_2.setAlignment(QtCore.Qt.AlignCenter)
        self.label_2.setObjectName("label_2")
        self.verticalLayout_2.addWidget(self.label_2)
        self.plainTextEdit_3 = QtWidgets.QPlainTextEdit(self.centralwidget)
        self.plainTextEdit_3.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;")
        self.plainTextEdit_3.setObjectName("plainTextEdit_3")
        self.verticalLayout_2.addWidget(self.plainTextEdit_3)
        self.verticalLayout_2.setStretch(0, 1)
        self.verticalLayout_2.setStretch(1, 8)
        self.verticalLayout_6.addLayout(self.verticalLayout_2)
        self.horizontalLayout_3.addLayout(self.verticalLayout_6)
        self.horizontalLayout_3.setStretch(0, 5)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1279, 22))
        self.menubar.setStyleSheet("background-color: #31363b; color: #eff0f1;")
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setStyleSheet("background-color: #31363b; color: #eff0f1;")
        self.menuFile.setObjectName("menuFile")
        self.menuEdit = QtWidgets.QMenu(self.menubar)
        self.menuEdit.setStyleSheet("background-color: #31363b; color: #eff0f1;")
        self.menuEdit.setObjectName("menuEdit")
        self.menuSettings = QtWidgets.QMenu(self.menubar)
        self.menuSettings.setStyleSheet("background-color: #31363b; color: #eff0f1;")
        self.menuSettings.setObjectName("menuSettings")
        self.menuTheme_select = QtWidgets.QMenu(self.menuSettings)
        icon227 = QtGui.QIcon()
        icon227.addPixmap(QtGui.QPixmap("Choose_theme-512.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.menuTheme_select.setIcon(icon227)
        self.menuTheme_select.setStyleSheet("background-color: #31363b; color: #eff0f1;")
        self.menuTheme_select.setObjectName("menuTheme_select")
        self.menuAbout = QtWidgets.QMenu(self.menubar)
        self.menuAbout.setStyleSheet("background-color: #31363b; color: #eff0f1;")
        self.menuAbout.setObjectName("menuAbout")
        self.menuRun = QtWidgets.QMenu(self.menubar)
        self.menuRun.setStyleSheet("background-color: #31363b; color: #eff0f1;")
        self.menuRun.setObjectName("menuRun")
        self.menuSelect_Core = QtWidgets.QMenu(self.menuRun)
        icon231=QtGui.QIcon()
        icon231.addPixmap(QtGui.QPixmap(":/Icons/icons8-microchip-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.menuSelect_Core.setIcon(icon231)
        self.menuSelect_Core.setStyleSheet("background-color: #31363b; color: #eff0f1;")
        self.menuSelect_Core.setObjectName("menuSelect_Core")
        self.menuExtensions = QtWidgets.QMenu(self.menubar)
        self.menuExtensions.setStyleSheet("background-color: #31363b; color: #eff0f1;")
        self.menuExtensions.setObjectName("menuExtensions")
        MainWindow.setMenuBar(self.menubar)
        self.toolButton = QtWidgets.QToolButton()
        self.toolButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.toolButton.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;")
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(":/Icons/icons8-microchip-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.toolButton.setIcon(icon)
        self.toolButton.setIconSize(QtCore.QSize(45, 24))
        self.toolButton.setPopupMode(QtWidgets.QToolButton.InstantPopup)
        self.toolButton.setObjectName("toolButton")
        self.toolBar = QtWidgets.QToolBar(MainWindow)
        self.toolBar.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.toolBar.setAcceptDrops(False)
        self.toolBar.setLayoutDirection(QtCore.Qt.RightToLeft)
        self.toolBar.setStyleSheet("border: 0.1ex transparent #393838;background: 0.1ex solid #31363b;font-weight: bold;")
        self.toolBar.setMovable(False)
        self.toolBar.setAllowedAreas(QtCore.Qt.NoToolBarArea)
        self.toolBar.setIconSize(QtCore.QSize(45, 24))
        self.toolBar.setObjectName("toolBar")
        
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.statusBar = QtWidgets.QStatusBar(MainWindow)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.statusBar.sizePolicy().hasHeightForWidth())
        self.statusBar.setSizePolicy(sizePolicy)
        self.statusBar.setStyleSheet("background-color: rgb(0,128,0,75%);")
        self.statusBar.setObjectName("statusBar")
        MainWindow.setStatusBar(self.statusBar)
        self.spacer=QtWidgets.QWidget()
        self.spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.uit = QtWidgets.QAction(MainWindow)
        icon22 = QtGui.QIcon()
        icon22.addPixmap(QtGui.QPixmap("uit.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.uit.setIcon(icon22)
        self.uit.setShortcutVisibleInContextMenu(True)
        self.uit.setObjectName("actionNew")
        self.uit.triggered.connect(self.open_uit)
        
        self.merl = QtWidgets.QAction(MainWindow)
        icon23 = QtGui.QIcon()
        icon23.addPixmap(QtGui.QPixmap("merl.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.merl.setIcon(icon23)
        self.merl.setShortcutVisibleInContextMenu(True)
        self.merl.setObjectName("actionNew")
        self.merl.triggered.connect(self.open_site)

        
        self.About = QtWidgets.QAction(MainWindow)
        icon21 = QtGui.QIcon()
        icon21.addPixmap(QtGui.QPixmap("About_logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.About.setIcon(icon21)
        self.About.setShortcutVisibleInContextMenu(True)
        self.About.setObjectName("actionNew")
        self.About.triggered.connect(self.about_dark)
        self.actionNew = QtWidgets.QAction(MainWindow)




        
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap(":/Icons/icons8-add-property-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionNew.setIcon(icon1)
        self.actionNew.setShortcutVisibleInContextMenu(True)
        self.actionNew.setObjectName("actionNew")
        self.actionNew.triggered.connect(self.untitled)
        self.actionOpen = QtWidgets.QAction(MainWindow)
        icon2 = QtGui.QIcon()
        icon2.addPixmap(QtGui.QPixmap(":/Icons/icons8-upload-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionOpen.setIcon(icon2)
        self.actionOpen.setObjectName("actionOpen")
        self.actionOpen.triggered.connect(self.open_dialog_box)
        
        self.actionsave = QtWidgets.QAction(MainWindow)
        icon3 = QtGui.QIcon()
        icon3.addPixmap(QtGui.QPixmap(":/Icons/icons8-save-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionsave.setIcon(icon3)
        self.actionsave.setShortcutVisibleInContextMenu(True)
        self.actionsave.setObjectName("actionsave")
        self.actionsave.triggered.connect(self.save_temp)
        self.actionsave.setShortcut("Ctrl+s")
        self.actionundo = QtWidgets.QAction(MainWindow)
        icon4 = QtGui.QIcon()
        icon4.addPixmap(QtGui.QPixmap(":/Icons/icons8-undo-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionundo.setIcon(icon4)
        self.actionundo.setVisible(True)
        self.actionundo.setShortcut("Ctrl+Z")
        self.actionundo.triggered.connect(self.plainTextEdit.undo)
        self.actionundo.setShortcutVisibleInContextMenu(True)
        self.actionundo.setObjectName("actionundo")
        self.actionRedo = QtWidgets.QAction(MainWindow)
        icon5 = QtGui.QIcon()
        icon5.addPixmap(QtGui.QPixmap(":/Icons/icons8-redo-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionRedo.setIcon(icon5)
        self.actionRedo.setShortcutVisibleInContextMenu(True)
        self.actionRedo.setObjectName("actionRedo")
        self.actionRedo.setShortcut("Ctrl+Shift+Z")
        self.actionRedo.triggered.connect(self.plainTextEdit.redo)
        self.actioncut = QtWidgets.QAction(MainWindow)
        icon6 = QtGui.QIcon()
        icon6.addPixmap(QtGui.QPixmap(":/Icons/icons8-cut-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actioncut.setIcon(icon6)
        self.actioncut.setShortcutVisibleInContextMenu(True)
        self.actioncut.setShortcut("Ctrl+X")
        self.actioncut.triggered.connect(self.plainTextEdit.cut)
        self.actioncut.setObjectName("actioncut")
        self.actioncopy = QtWidgets.QAction(MainWindow)
        icon7 = QtGui.QIcon()
        icon7.addPixmap(QtGui.QPixmap(":/Icons/icons8-copy-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actioncopy.setIcon(icon7)
        self.actioncopy.setShortcutVisibleInContextMenu(True)
        self.actioncopy.setObjectName("actioncopy")
        self.actioncopy.setShortcut("Ctrl+C")
        self.actioncopy.triggered.connect(self.plainTextEdit.copy)
        self.actionpaste = QtWidgets.QAction(MainWindow)
        icon8 = QtGui.QIcon()
        icon8.addPixmap(QtGui.QPixmap(":/Icons/icons8-paste-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionpaste.setIcon(icon8)
        self.actionpaste.setShortcutVisibleInContextMenu(True)
        self.actionpaste.setObjectName("actionpaste")
        self.actionpaste.setShortcut("Ctrl+V")
        self.actionpaste.triggered.connect(self.plainTextEdit.paste)
        self.actionFind = QtWidgets.QAction(MainWindow)
        icon9 = QtGui.QIcon()
        icon9.addPixmap(QtGui.QPixmap(":/Icons/icons8-search-property-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionFind.setIcon(icon9)
        self.actionFind.setShortcutVisibleInContextMenu(True)
        self.actionFind.setObjectName("actionFind")
        self.actionFind.setShortcut("Ctrl+F")
        self.actionFind.triggered.connect(find.Find(self.plainTextEdit).show)
        self.actionDark = QtWidgets.QAction(MainWindow)
        self.actionDark.setObjectName("actionDark")
        self.actionMERL = QtWidgets.QAction(MainWindow)
        icon228 = QtGui.QIcon()
        icon228.addPixmap(QtGui.QPixmap("merl.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionMERL.setIcon(icon228)
        self.actionMERL.setObjectName("actionMERL")
        self.actionMERL.triggered.connect(self.open_site)
        self.actionhelp = QtWidgets.QAction(MainWindow)
        self.actionhelp.setObjectName("actionhelp")
        icon229 = QtGui.QIcon()
        icon229.addPixmap(QtGui.QPixmap("About_logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionhelp.setIcon(icon229)
        
        self.actionhelp.triggered.connect(self.about_dark)
        self.actionRun = QtWidgets.QAction(MainWindow)
        icon11 = QtGui.QIcon()
        icon11.addPixmap(QtGui.QPixmap(":/Icons/icons8-play-property-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionRun.setIcon(icon11)
        self.actionRun.setObjectName("actionRun")
        self.actionRun.triggered.connect(self.run_Burq)
        self.actionRun.setEnabled(False)
        
        self.actionSave_As = QtWidgets.QAction(MainWindow)
        icon13 = QtGui.QIcon()
        icon13.addPixmap(QtGui.QPixmap(":/Icons/icons8-save-as-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionSave_As.setIcon(icon13)
        self.actionSave_As.setObjectName("actionSave_As")
        self.actionsave.triggered.connect(self.saveAs)
        self.actionsave.setShortcut("Ctrl+Shift+s")
        self.actionHigh_Contrast = QtWidgets.QAction(MainWindow)
        self.actionHigh_Contrast.setObjectName("actionHigh_Contrast")
        self.actionHigh_Contrast.triggered.connect(self.light_theme)
        self.actionChisel_Core = QtWidgets.QAction(MainWindow)
        icon14 = QtGui.QIcon()
        icon14.addPixmap(QtGui.QPixmap(":/Icons/icons8-nail-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionChisel_Core.setIcon(icon14)
        self.actionChisel_Core.setObjectName("actionChisel_Core")
        self.actionVerilog = QtWidgets.QAction(MainWindow)
        self.actionVerilog.setObjectName("actionVerilog")
        icon230 = QtGui.QIcon()
        icon230.addPixmap(QtGui.QPixmap("Verilator_logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionVerilog.setIcon(icon230)
        self.actionDebug = QtWidgets.QAction(MainWindow)
        icon15 = QtGui.QIcon()
        icon15.addPixmap(QtGui.QPixmap(":/Icons/icons8-bug-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionDebug.setIcon(icon15)
        self.actionDebug.setObjectName("actionDebug")
        self.actionDebug.triggered.connect(self.termclose)
        
        self.actionCompile = QtWidgets.QAction(MainWindow)
        icon16 = QtGui.QIcon()
        icon16.addPixmap(QtGui.QPixmap(":/Icons/icons8-new-property-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionCompile.setIcon(icon16)
        self.actionCompile.setObjectName("actionCompile")
        self.actionCompile.triggered.connect(self.compile_Code)
        self.actionB_I = QtWidgets.QAction(MainWindow)
        self.actionB_I.setObjectName("actionB_I")
        icon232=QtGui.QIcon()
        icon232.addPixmap(QtGui.QPixmap("micro.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionB_I.setIcon(icon232)
        
        self.actionB_I_C = QtWidgets.QAction(MainWindow)
        self.actionB_I_C.setObjectName("actionB_I_C")
        icon233=QtGui.QIcon()
        icon233.addPixmap(QtGui.QPixmap("micro1.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionB_I_C.setIcon(icon233)
        
        self.actionB_I_M = QtWidgets.QAction(MainWindow)
        self.actionB_I_M.setObjectName("actionB_I_M")
        icon234=QtGui.QIcon()
        icon234.addPixmap(QtGui.QPixmap("micro2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionB_I_M.setIcon(icon234)
        self.menuFile.addAction(self.actionNew)
        self.menuFile.addAction(self.actionOpen)
        
        self.menuFile.addAction(self.actionsave)
        self.menuFile.addAction(self.actionSave_As)
        self.menuEdit.addAction(self.actionundo)
        self.menuEdit.addAction(self.actionRedo)
        self.menuEdit.addAction(self.actioncut)
        self.menuEdit.addAction(self.actioncopy)
        self.menuEdit.addAction(self.actionpaste)
        self.menuEdit.addAction(self.actionFind)
        self.menuTheme_select.addAction(self.actionDark)
        self.menuTheme_select.addAction(self.actionHigh_Contrast)
        self.menuSettings.addAction(self.menuTheme_select.menuAction())
        self.menuSettings.addSeparator()
        
        self.menuAbout.addAction(self.actionMERL)
        self.menuAbout.addAction(self.actionhelp)
        self.menuSelect_Core.addSeparator()
        self.menuSelect_Core.addSeparator()
        self.menuSelect_Core.addAction(self.actionChisel_Core)
        self.menuSelect_Core.addAction(self.actionVerilog)
        self.menuRun.addAction(self.actionRun)
        self.menuRun.addAction(self.actionCompile)
        self.menuRun.addAction(self.menuSelect_Core.menuAction())
        self.menuRun.addAction(self.actionDebug)
       
        self.menuExtensions.addAction(self.actionB_I)
        self.menuExtensions.addAction(self.actionB_I_C)
        self.menuExtensions.addAction(self.actionB_I_M)
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuEdit.menuAction())
        self.menubar.addAction(self.menuSettings.menuAction())
        self.menubar.addAction(self.menuAbout.menuAction())
        self.menubar.addAction(self.menuExtensions.menuAction())
        self.menubar.addAction(self.menuRun.menuAction())
        self.toolBar.addAction(self.actionDebug)
        self.toolBar.addAction(self.actionChisel_Core)
        self.toolBar.addAction(self.actionVerilog)
        self.toolBar.addSeparator()
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.actionRun)
        self.toolBar.addAction(self.actionCompile)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.actionFind)
        self.toolBar.addAction(self.actionsave)
        self.toolBar.addAction(self.actionNew)
        self.toolBar.addSeparator()
        self.toolBar.addWidget(self.toolButton)
        self.toolButton.addAction(self.actionB_I)
        self.toolButton.addAction(self.actionB_I_C)
        self.toolButton.addAction(self.actionB_I_M)
        self.toolBar.addWidget(self.spacer)
        self.toolBar.addAction(self.About)
        self.toolBar.addAction(self.uit)
        self.toolBar.addAction(self.merl)
        self.toolBar.addSeparator()
        self.toolBar.addSeparator()

        self.actionB_I_C.triggered.connect(self.myfun)

        self.retranslateUi(MainWindow)
        self.tabWidget_2.setCurrentIndex(0)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.count_myfun = 2
        self.plainTextEdit_2.isReadOnly()
        self.plainTextEdit_3.isReadOnly()
 		



    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "BURQ IDE"))
        MainWindow.setWindowIcon(QIcon("About_logo.png"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab), _translate("MainWindow", "Untitled"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab1), _translate("MainWindow", "Terminal"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Output"))
        self.label_3.setText(_translate("MainWindow", "ASSEMBLY CODE"))
        self.label_2.setText(_translate("MainWindow", "MACHINE CODE"))
        self.toolButton.setText(_translate("MainWindow", "..."))
        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.menuEdit.setTitle(_translate("MainWindow", "Edit"))
        self.menuSettings.setTitle(_translate("MainWindow", "Settings"))
        self.menuTheme_select.setTitle(_translate("MainWindow", "Theme select"))
        self.menuAbout.setTitle(_translate("MainWindow", "About"))
        self.menuRun.setTitle(_translate("MainWindow", "Run"))
        self.menuSelect_Core.setTitle(_translate("MainWindow", "Select Core"))
        self.menuExtensions.setTitle(_translate("MainWindow", "Extensions"))
        self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
        self.actionNew.setText(_translate("MainWindow", "New"))
        self.actionNew.setShortcut(_translate("MainWindow", "Ctrl+N"))
        self.actionOpen.setText(_translate("MainWindow", "Import"))
        self.actionOpen.setShortcut(_translate("MainWindow","Ctrl+O"))
        
        self.actionsave.setText(_translate("MainWindow", "Save"))
        self.actionsave.setShortcut(_translate("MainWindow", "Ctrl+S"))
        self.actionundo.setText(_translate("MainWindow", "undo"))
        self.actionundo.setShortcut(_translate("MainWindow", "Ctrl+Z"))
        self.actionRedo.setText(_translate("MainWindow", "Redo"))
        self.actionRedo.setShortcut(_translate("MainWindow", "Ctrl+Y"))
        self.actioncut.setText(_translate("MainWindow", "cut"))
        self.actioncut.setShortcut(_translate("MainWindow", "Ctrl+X"))
        self.actioncopy.setText(_translate("MainWindow", "copy"))
        self.actioncopy.setShortcut(_translate("MainWindow", "Ctrl+V"))
        self.actionpaste.setText(_translate("MainWindow", "paste"))
        self.actionpaste.setShortcut(_translate("MainWindow", "Ctrl+V"))
        self.actionFind.setText(_translate("MainWindow", "Find"))
        self.actionFind.setShortcut(_translate("MainWindow", "Ctrl+F"))
        self.actionDark.setText(_translate("MainWindow", "Dracula"))
        self.actionMERL.setText(_translate("MainWindow", "MERL"))
        self.actionhelp.setText(_translate("MainWindow", "help"))
        
        self.actionRun.setText(_translate("MainWindow", "Run"))
        self.About.setText(_translate("MainWindow", "About IDE"))
        
        self.actionSave_As.setText(_translate("MainWindow", "Save As"))
        self.actionSave_As.setShortcut(_translate("MainWindow","Crtl+Shift+S"))
        self.actionHigh_Contrast.setText(_translate("MainWindow", "High Contrast"))
        self.actionChisel_Core.setText(_translate("MainWindow", "Chisel"))
        self.actionVerilog.setText(_translate("MainWindow", "Verilog"))
        self.actionDebug.setText(_translate("MainWindow", "Cancel Process"))
        
        self.actionCompile.setText(_translate("MainWindow", "Compile"))
        self.actionB_I.setText(_translate("MainWindow", "I-Extension"))
        self.actionB_I_C.setText(_translate("MainWindow", "IC-Extension"))
        self.actionB_I_M.setText(_translate("MainWindow", "IM-Extension"))
        self.uit.setText(_translate("MainWindow", "UIT Website"))
        self.merl.setText(_translate("MainWindow", "MERL Website"))

    def myfun(self):
        from subprocess import call
        if self.count_myfun % 2 == 0:
            #os.system('python Extraction.py')
            call(["python3", "Extraction.py"])
            file = open("c_converted_machine.txt", "r")
            assembly = file.read()
            file.close()
            self.plainTextEdit_3.setPlainText(assembly)
            self.count_myfun += 1
            
        else:
            self.read_MachineCode()
            self.count_myfun += 1
            
    def on_clicked(self, index):
        self.num+=1
        self.tabWidget_2.setCurrentIndex(self.num)
        a=setattr(self,"tab",self.num)
        path = self.fileModel.fileInfo(index).absoluteFilePath()
        self.treeView.setRootIndex(self.fileModel.setRootPath(path))
        print(path)
        with open(path, "r") as f:
            print(f.readline())
        ff = open(path,"r")
        c_read = ff.read()
        #Tab Reading for index values 
        a= QtWidgets.QWidget()
        a.setObjectName("tab"+str(self.num))
        self.verticalLayout_7 = QtWidgets.QVBoxLayout(a)
        self.verticalLayout_7.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_7.setSpacing(0)
        self.verticalLayout_7.setObjectName("verticalLayout_7")
        self.tabWidget_2.setTabsClosable(True)
        self.tabWidget_2.tabCloseRequested.connect(self.removeTab)
        self.plainTextEdit = LineNumber_dark.QCodeEditor(a)
        self.highlighter=hightest_dark.Highlighter(self.plainTextEdit.document())
        self.plainTextEdit.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;")
        self.plainTextEdit.setObjectName("plainTextEdit")
        self.plainTextEdit.textChanged.connect(self.changed)
        self.verticalLayout_7.addWidget(self.plainTextEdit)
        self.tabWidget_2.addTab(a, path)
        self.plainTextEdit.setPlainText(c_read)
        self.actionFind.triggered.connect(find.Find(self.plainTextEdit).show)

    def removeTab(self, index):
        print(index)
        widget = self.tabWidget_2.widget(index)
        if widget is not None:
            widget.deleteLater()

    def untitled(self,index):
        self.num+=1
        self.tabWidget_2.setCurrentIndex(self.num)
        a=setattr(self,"tab",self.num)
        #Tab Reading for index values 
        a= QtWidgets.QWidget()
        a.setObjectName("tab"+str(self.num))
        self.verticalLayout_7 = QtWidgets.QVBoxLayout(a)
        self.verticalLayout_7.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_7.setSpacing(0)
        self.verticalLayout_7.setObjectName("verticalLayout_7")
        self.tabWidget_2.setTabsClosable(True)
        self.tabWidget_2.tabCloseRequested.connect(self.removeTab)
        self.plainTextEdit = LineNumber_dark.QCodeEditor(a)
        self.highlighter=hightest_dark.Highlighter(self.plainTextEdit.document())
        self.plainTextEdit.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;")
        self.plainTextEdit.setObjectName("plainTextEdit")
        self.plainTextEdit.textChanged.connect(self.changed)
        self.verticalLayout_7.addWidget(self.plainTextEdit)
        self.tabWidget_2.addTab(a, self.temptab)
        self.filename=self.temptab
        self.plainTextEdit.setPlainText("")
        self.actionFind.triggered.connect(find.Find(self.plainTextEdit).show)
        
    def open_dialog_box(self):
        filename = QFileDialog.getOpenFileName()
        path = filename[0]
        print(path)
        with open(path, "r") as f:
            print(f.readline())

        ff = open(path,"r")
        c_read = ff.read()
        #Tab Read initialise
        self.num+=1
        self.tabWidget_2.setCurrentIndex(self.num)
        a=setattr(self,"tab",self.num)
        #Tab Read 13
        a= QtWidgets.QWidget()
        a.setObjectName("tab"+str(self.num))
        self.verticalLayout_7 = QtWidgets.QVBoxLayout(a)
        self.verticalLayout_7.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_7.setSpacing(0)
        self.verticalLayout_7.setObjectName("verticalLayout_7")
        self.tabWidget_2.setTabsClosable(True)
        self.tabWidget_2.tabCloseRequested.connect(self.removeTab)
        self.plainTextEdit = LineNumber_dark.QCodeEditor(a)
        self.highlighter=hightest_dark.Highlighter(self.plainTextEdit.document())
        self.plainTextEdit.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;")
        self.plainTextEdit.setObjectName("plainTextEdit")
        self.plainTextEdit.textChanged.connect(self.changed)
        self.verticalLayout_7.addWidget(self.plainTextEdit)
        self.tabWidget_2.addTab(a, path)
        self.plainTextEdit.setPlainText(c_read)
        self.actionFind.triggered.connect(find.Find(self.plainTextEdit).show)

    

    def run_Command(self, command = "ls"):
        program = "tmux"
        options = []
        #options.extend(["send-keys"])
        options.extend([command])
        options.extend(["\r"])
        print(options)
        for data in range(len(options)):
            self.tab1.sendText(options[data])
        
        
       

    def read_MachineCode(self):
        file = open("/home/monis/learning-journey3/machinecode.txt", "r")
        machineCode = file.read()
        file.close()
        self.plainTextEdit_3.setPlainText(machineCode)
        

    def read_AssemblyCode(self):
        file = open("/home/monis/learning-journey3/machine.txt", "r")
        assembly = file.read()
        file.close()
        self.plainTextEdit_2.setPlainText(assembly)
        

    def save_Code(self):
        file = open("/home/monis/learning-journey3/test.c", "w")
        code = self.plainTextEdit.toPlainText()
        file.write(code)
        file.close()

    def compile_Code(self):
        self.actionRun.setEnabled(False)
        self.save_Code()
        self.plainTextEdit_2.setPlainText("")
        self.plainTextEdit_3.setPlainText("")
        self.run_Command("cd /home/monis/learning-journey3")
        self.run_Command("./script2.sh")
        thread=threading.Thread(target=self.error_check)
        thread.start()

    def termclose(self):
        self.getcode() 

    def output(self):
        import re
        time.sleep(0.5)
        file=open("/home/monis/learning-journey3/output.txt", "r")
        self.out12=file.read()
        file.close()
        self.plainTextEdit23.setPlainText(self.out12)
        
    def error_check(self):   ##Error Check by GCC Line Number
        import re
        time.sleep(0.5)
        file = open("/home/monis/learning-journey3/meralog.txt", "r")
        assembly = file.read()
        x = re.findall("    [0-9] |   [1-9999][0-9999] ",assembly)
        
        if x==[]:
            print("No errors")
            self.actionRun.setEnabled(True)
            file.close()
        else:
            error_line=int(x[-1])
            self.plainTextEdit.highlightErrorLine(error_line-1)
            self.actionRun.setEnabled(False)
            print(error_line)
            file.close()

    def run_Burq(self):
        self.read_AssemblyCode()
        self.read_MachineCode()
        self.run_Command("cd /home/monis/learning-journey3")
        self.run_Command("./script3.sh")
        self.output()

    def getcode(self):
        self.run_Command("cd /home/monis/learning-journey3")
        self.run_Command("./script4.sh")
        self.output()
        
    def open_site(self):
        webbrowser.open('https://www.merledupk.org/')

    def open_uit(self):
        webbrowser.open('https://www.uit.edu')

    def light_theme(self):
        MainWindow.close()
        from subprocess import call
        call(["python3", "LightW.py"])
    def about_dark(self):
        from subprocess import call
        call(["python3", "about_dark.py"])

    def changed(self):
        self.changesSaved = False
        

    
    def save_temp(self):
        print(self.changesSaved)
        print(self.filename)
        if self.changesSaved ==True:
            pass
        elif self.changesSaved ==False:
            self.saveAs()
        
            
            
    def saveAs(self): 
        if self.filename =="untitled" or self.filename =="NewTest.C":
            self.filename = QtWidgets.QFileDialog.getSaveFileName()[0]
            self.changesSaved = True
            f=open(self.filename,'w')
            f.write(self.plainTextEdit.toPlainText())
            
            
             
        elif self.filename =="":
            self.filename = QtWidgets.QFileDialog.getSaveFileName()[0]
            self.changesSaved = True
            f=open(self.filename,'w')
            f.write(self.plainTextEdit.toPlainText())
            
            
        elif self.filename !="" and self.filename !="untitled" and self.filename !="NewTest.C":
            f=open(self.filename,'w')
            f.write(self.plainTextEdit.toPlainText())

    def closeEvent(self, event):

        if self.changesSaved:

            event.accept()

        else:
        
            popup = QtWidgets.QMessageBox(MainWindow)

            popup.setIcon(QtWidgets.QMessageBox.Warning)
            
            popup.setText("The document has been modified")
            
            popup.setInformativeText("Do you want to save your changes?")
            
            popup.setStandardButtons(QtWidgets.QMessageBox.Save   |
                                      QtWidgets.QMessageBox.Cancel |
                                      QtWidgets.QMessageBox.Discard)
            
            popup.setDefaultButton(QtWidgets.QMessageBox.Save)

            answer = popup.exec_()

            if answer == QtWidgets.QMessageBox.Save:
                self.save_temp()

            elif answer == QtWidgets.QMessageBox.Discard:
                event.accept()

            else:
                event.ignore()
class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = 'Whenson\'s Custom INI Merger'
        self.geo = (200, 200, 800, 600)
        self.initGUI()

    def initGUI(self):
        # windows title and geometry
        self.setGeometry(*(self.geo))
        self.setWindowTitle(self.title)
        self.show()

        # master layout and widget definition
        self.layout = QHBoxLayout()

        self.file_box = QVBoxLayout()

        self.list_box = QVBoxLayout()
        self.btn_group = QVBoxLayout()

        # deploy layout
        self.setLayout(self.layout)
        self.layout.addLayout(self.file_box)

        self.layout.addLayout(self.list_box)
        self.layout.addLayout(self.btn_group)

        # file box
        self.file_box.addWidget(QLabel('File Browser'))
        self.folder_tree = QTreeView()
        self.file_box.addWidget(self.folder_tree)
        self.file_list = QTreeView()
        self.file_box.addWidget(self.file_list)

        # list box

        self.normal_list = DropListWidget()
        self.demo_list = DropListWidget()

        self.list_box.addWidget(QLabel('Output File'))
        self.list_box.addWidget(QLineEdit())

        self.list_box.addWidget(QLabel('Module List'))
        self.list_box.addWidget(self.normal_list)

        temp = QHBoxLayout()
        self.up_btn = QPushButton()
        self.up_btn.setText('ᐱ')
        self.down_btn = QPushButton()
        self.down_btn.setText('ᐯ')
        self.list_box.addLayout(temp)
        temp.addWidget(self.up_btn)
        temp.addWidget(self.down_btn)

        self.list_box.addWidget(QLabel('With Demostration'))
        self.list_box.addWidget(self.demo_list)

        # button group
        self.merge_btn = QPushButton('Merge')
        self.btn_group.addWidget(self.merge_btn)

        self.load_btn = QPushButton('Load')
        self.btn_group.addWidget(self.load_btn)

        self.init_file_tree()
        self.init_drag()

    def init_file_tree(self):
        self.dir_model = QFileSystemModel()
        self.dir_model.setRootPath('C:/')
        self.dir_model.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot)
        self.folder_tree.setModel(self.dir_model)
        self.folder_tree.hideColumn(1)
        self.folder_tree.hideColumn(2)
        self.folder_tree.hideColumn(3)

        self.file_model = QFileSystemModel()
        self.file_model.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.file_list.setModel(self.file_model)
        self.file_list.setRootIndex(self.file_model.setRootPath('C:/'))
        self.file_model.setNameFilters(['*.txt', '*.ini', '*.map'])
        self.file_model.setNameFilterDisables(False)
        self.folder_tree.clicked.connect(self.tree_on_clicked)
        self.file_list.setSelectionMode(QAbstractItemView.ExtendedSelection)

    def init_drag(self):
        self.file_list.setDragEnabled(True)
        self.file_list.setDropIndicatorShown(True)
        # self.file_list.setDefaultDropAction(Qt.MoveAction)

    def tree_on_clicked(self, index):
        path = self.dir_model.fileInfo(index).absoluteFilePath()
        self.file_list.setRootIndex(self.file_model.setRootPath(path))
Exemple #21
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self._ui = Ui_MainWindow()
        self._ui.setupUi(self)

        self._model = QFileSystemModel()
        self._model.setRootPath('/')

        self._setUpViews(self._ui.leftView)
        self._setUpViews(self._ui.rightView)

        self._setUpActions()

        self._setUpButtons()

    def _setUpViews(self, view):
        view.setModel(self._model)
        view.setRootIndex(self._model.index(self._model.rootPath()))
        view.doubleClicked.connect(self._view_doubleClicked)

    def _setUpActions(self):
        self._ui.actionNewFile.triggered.connect(self._newFile_triggered)
        self._ui.actionNewFolder.triggered.connect(self._newFolder_triggered)
        self._ui.actionProperties.triggered.connect(self._properties_triggered)
        self._ui.actionMove.triggered.connect(self._move_triggered)
        self._ui.actionCopy.triggered.connect(self._copy_triggered)
        self._ui.actionToTrash.triggered.connect(self._toTrash_triggered)
        self._ui.actionDelete.triggered.connect(self._delete_triggered)
        self._ui.actionOpenDefaultApp.triggered.connect(
            self._defaultApp_triggered)

    def _setUpButtons(self):
        self._ui.leftBackButton.clicked.connect(self._leftBack_clicked)
        self._ui.rightBackButton.clicked.connect(self._rightBack_clicked)
        self._ui.leftHomeButton.clicked.connect(self._leftHome_clicked)
        self._ui.rightHomeButton.clicked.connect(self._rightHome_clicked)

    def _newFile_triggered(self):
        print('newFile')
        path = self._getCurrentLocation()
        newFile, confirmed = QInputDialog.getText(self, 'Create new file',
                                                  'File name: ')

        if confirmed:
            try:
                filecommands.newFile(path + '/' + newFile, changeIfExists)
            except CreateFileError:
                throwError(f'Can NOT create file {newFile}')

    def _newFolder_triggered(self):
        print('newFolder')
        path = self._getCurrentLocation()
        newFolder, confirmed = QInputDialog.getText(self, 'Create new folder',
                                                    'Folder name: ')

        if confirmed:
            try:
                filecommands.newFolder(path + '/' + newFolder, changeIfExists)
            except CreateFolderError:
                throwError(f'Can NOT create folder {newFolder}')

    def _properties_triggered(self):
        print('properties')
        paths = self._getSelectedItemsPath()

        for path in paths:
            dialog = PropertiesDialog(path, changeIfExists)
            dialog.exec_()

    def _move_triggered(self):
        print('move')
        paths = self._getSelectedItemsPath()
        dst = self._getDestination()

        for path in paths:
            try:
                filecommands.move(path, dst, changeIfExists)
            except MoveFileError:
                throwError(f'Can NOT move {path} to {dst}')

    def _copy_triggered(self):
        print('copy')
        paths = self._getSelectedItemsPath()
        dst = self._getDestination()

        for path in paths:
            try:
                filecommands.copy(path, dst, changeIfExists)
            except CopyFileError:
                throwError(f'Can NOT copy {path} to {dst}')

    def _toTrash_triggered(self):
        print('toTrash')
        paths = self._getSelectedItemsPath()

        for path in paths:
            try:
                filecommands.moveToTrash(path)
            except MoveToTrashError:
                throwError(f'Can NOT move {path} to trash')

    def _delete_triggered(self):
        print('delete')
        paths = self._getSelectedItemsPath()

        for path in paths:
            try:
                filecommands.delete(path)
            except DeleteFileError:
                throwError(f'Can NOT delete {path}')

    def _defaultApp_triggered(self):
        print('default')
        paths = self._getSelectedItemsPath()

        for path in paths:
            try:
                filecommands.openWithDefaultApp(path)
            except OpenFileError:
                throwError(f'Can NOT open {path} with default app')

    def _leftBack_clicked(self):
        self._goBack(self._ui.leftView)

    def _rightBack_clicked(self):
        self._goBack(self._ui.rightView)

    def _leftHome_clicked(self):
        self._goHome(self._ui.leftView)

    def _rightHome_clicked(self):
        self._goHome(self._ui.rightView)

    def _view_doubleClicked(self, index):
        view = self.sender()
        firstColumnIndex = index.siblingAtColumn(0)
        fileInfo = self._model.fileInfo(firstColumnIndex)

        if fileInfo.isDir():
            if fileInfo.isReadable():
                view.setRootIndex(firstColumnIndex)
            else:
                message = QMessageBox(
                    QMessageBox.Critical, 'Permission denied',
                    f'Folder {fileInfo.fileName()} is not readable!')
                message.exec()
        elif fileInfo.isFile():
            try:
                filecommands.openWithDefaultApp(fileInfo.absoluteFilePath())
            except OpenFileError:
                message = QMessageBox(QMessageBox.Critical,
                                      'Can NOT open file',
                                      f'Can not open {fileInfo.fileName()}')
                message.exec()

    def _goBack(self, view):
        index = view.rootIndex()
        if index != self._model.index(filecommands.ROOT_PATH):
            view.setRootIndex(index.parent())

    def _goHome(self, view):
        view.setRootIndex(self._model.index(filecommands.ROOT_PATH))

    def _getSelectedItemsPath(self):
        return {
            self._model.fileInfo(index).absoluteFilePath()
            for index in self._ui.leftView.selectedIndexes()
        }

    def _getCurrentLocation(self):
        return self._model.fileInfo(
            self._ui.leftView.rootIndex()).absoluteFilePath()

    def _getDestination(self):
        return self._model.fileInfo(
            self._ui.rightView.rootIndex()).absoluteFilePath()
Exemple #22
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(670, 471)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.centralwidget.sizePolicy().hasHeightForWidth())
        self.centralwidget.setSizePolicy(sizePolicy)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        self.treeView = QtWidgets.QTreeView(self.centralwidget)
        self.treeView.setObjectName("treeView")
        self.treeView.setSortingEnabled(True)
        path = QDir.rootPath()

        self.dirModel = QFileSystemModel()
        self.dirModel.setRootPath(QDir.rootPath())

        self.fileModel = QFileSystemModel()
        self.fileModel.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.model = QtWidgets.QFileSystemModel()
        self.model.setRootPath((QtCore.QDir.rootPath()))
        self.treeView.setModel(self.model)
        self.treeView.setRootIndex(self.dirModel.index(path))
        self.treeView.doubleClicked.connect(self.on_clicked)
        self.treeView.setObjectName("treeView")
        self.treeView.setColumnWidth(0, 300)
        self.gridLayout.addWidget(self.treeView, 0, 3, 9, 1)

        self.comboBox = QtWidgets.QComboBox(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored,
                                           QtWidgets.QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.comboBox.sizePolicy().hasHeightForWidth())
        self.comboBox.setSizePolicy(sizePolicy)
        self.comboBox.setObjectName("comboBox")
        self.comboBox.setEditable(True)

        self.gridLayout.addWidget(self.comboBox, 1, 0, 1, 3)
        self.label = QtWidgets.QLabel(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed,
                                           QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.label.sizePolicy().hasHeightForWidth())
        self.label.setSizePolicy(sizePolicy)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.comboBox_2 = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox_2.setEnabled(True)
        self.comboBox_2.setEditable(True)

        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.comboBox_2.sizePolicy().hasHeightForWidth())
        self.comboBox_2.setSizePolicy(sizePolicy)
        self.comboBox_2.setObjectName("comboBox_2")
        self.gridLayout.addWidget(self.comboBox_2, 3, 0, 1, 3)
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed,
                                           QtWidgets.QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.label_3.sizePolicy().hasHeightForWidth())
        self.label_3.setSizePolicy(sizePolicy)
        self.label_3.setObjectName("label_3")
        self.gridLayout.addWidget(self.label_3, 4, 0, 1, 1)
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed,
                                           QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.label_2.sizePolicy().hasHeightForWidth())
        self.label_2.setSizePolicy(sizePolicy)
        self.label_2.setObjectName("label_2")
        self.gridLayout.addWidget(self.label_2, 2, 0, 1, 3)

        logoPath = QDir.homePath()
        self.logoModel = QFileSystemModel()
        self.logoModel.setRootPath(logoPath)
        self.logoModel.setFilter(QDir.NoDotAndDotDot | QDir.Files
                                 | QDir.NoSymLinks)
        print(logoPath)
        self.comboBox_3 = QtWidgets.QComboBox(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.comboBox_3.sizePolicy().hasHeightForWidth())
        self.comboBox_3.setSizePolicy(sizePolicy)
        self.comboBox_3.setObjectName("comboBox_3")
        self.comboBox_3.setModel(self.logoModel)
        self.comboBox_3.setEditable(True)

        self.gridLayout.addWidget(self.comboBox_3, 5, 0, 1, 3)
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.groupBox.sizePolicy().hasHeightForWidth())
        self.groupBox.setSizePolicy(sizePolicy)
        self.groupBox.setObjectName("groupBox")
        self.checkBox = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox.setGeometry(QtCore.QRect(10, 20, 70, 17))
        self.checkBox.setObjectName("checkBox")
        self.checkBox_2 = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_2.setGeometry(QtCore.QRect(10, 50, 70, 17))
        self.checkBox_2.setObjectName("checkBox_2")
        self.checkBox_3 = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_3.setGeometry(QtCore.QRect(10, 80, 70, 17))
        self.checkBox_3.setObjectName("checkBox_3")
        self.checkBox_4 = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_4.setGeometry(QtCore.QRect(10, 110, 131, 17))
        self.checkBox_4.setObjectName("checkBox_4")
        self.gridLayout.addWidget(self.groupBox, 7, 0, 1, 2)
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed,
                                           QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.pushButton.sizePolicy().hasHeightForWidth())
        self.pushButton.setSizePolicy(sizePolicy)
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setObjectName("pushButton_2")
        self.gridLayout.addWidget(self.pushButton, 6, 0, 1, 1)
        self.gridLayout.addWidget(self.pushButton_2, 6, 1, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 670, 21))
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.menuEdit = QtWidgets.QMenu(self.menubar)
        self.menuEdit.setObjectName("menuEdit")
        self.menuHelp = QtWidgets.QMenu(self.menubar)
        self.menuHelp.setObjectName("menuHelp")
        MainWindow.setMenuBar(self.menubar)
        self.actionOpen = QtWidgets.QAction(MainWindow)
        self.actionOpen.setObjectName("actionOpen")
        self.actionSearch_from_a_specific_Folder = QtWidgets.QAction(
            MainWindow)
        self.actionSearch_from_a_specific_Folder.setObjectName(
            "actionSearch_from_a_specific_Folder")
        self.actionCut = QtWidgets.QAction(MainWindow)
        self.actionCut.setObjectName("actionCut")
        self.actionCopy = QtWidgets.QAction(MainWindow)
        self.actionCopy.setObjectName("actionCopy")
        self.actionPaste = QtWidgets.QAction(MainWindow)
        self.actionPaste.setObjectName("actionPaste")
        self.actionAbout = QtWidgets.QAction(MainWindow)
        self.actionAbout.setObjectName("actionAbout")
        self.menuFile.addAction(self.actionOpen)
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionSearch_from_a_specific_Folder)
        self.menuEdit.addAction(self.actionCut)
        self.menuEdit.addAction(self.actionCopy)
        self.menuEdit.addAction(self.actionPaste)
        self.menuEdit.addSeparator()
        self.menuHelp.addAction(self.actionAbout)
        self.menuHelp.addSeparator()
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuEdit.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(
            _translate("MainWindow", "Search for files or folders"))
        self.label_3.setText(_translate("MainWindow", "TextLabel"))
        self.label_2.setText(_translate("MainWindow", "Containing Text"))
        self.groupBox.setTitle(_translate("MainWindow", "Options"))
        self.checkBox.setText(_translate("MainWindow", "Date"))
        self.checkBox_2.setText(_translate("MainWindow", "Size"))
        self.checkBox_3.setText(_translate("MainWindow", "Type"))
        self.checkBox_4.setText(_translate("MainWindow", "Advance Options"))
        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.menuEdit.setTitle(_translate("MainWindow", "Edit"))
        self.menuHelp.setTitle(_translate("MainWindow", "Help"))
        self.actionOpen.setText(_translate("MainWindow", "Open"))
        self.actionSearch_from_a_specific_Folder.setText(
            _translate("MainWindow", "Search from a specific Folder"))
        self.actionCut.setText(_translate("MainWindow", "Cut"))
        self.actionCopy.setText(_translate("MainWindow", "Copy (Ctrl +C)"))
        self.actionPaste.setText(_translate("MainWindow", "Paste (Ctrl + P)"))
        self.actionAbout.setText(_translate("MainWindow", "About"))
        self.pushButton.setText(_translate("MainWindow", "Search"))
        self.pushButton.clicked.connect(self.search)
        self.pushButton_2.setText(_translate("MainWindow", "Stop"))
        self.pushButton_2.clicked.connect(self.stop)

    def on_clicked(self, index):
        path = self.fileModel.fileInfo(index).absoluteFilePath()
        #Tab Reading for index values
        os.startfile(path)

    def stop(self):
        print("Program Stoped")
        self.pushButton.setEnabled(True)

    def search(self):
        print("Search started")
        self.pushButton.setEnabled(False)
        file_name = self.comboBox.currentText()
        print(file_name)
        path_tmp1 = self.comboBox_3.currentText()
        print(path_tmp1)
        path_tmp = re.findall("[A-Z]:", path_tmp1)
        print(path_tmp[-1])
        cur_dir = path_tmp[-1] + '/' ''
        print(cur_dir)

        result = []
        # Wlaking top-down from the root
        if file_name == "":
            pass
        else:
            for root, dir, files in os.walk(cur_dir):
                for i in files:
                    b = re.findall(".*" + file_name + ".*.*", i, re.IGNORECASE)
                    if b == []:
                        pass
                    elif b != []:
                        for i in files:
                            if b[-1] == i:
                                result.append(os.path.join(root, b[-1]))
            if result != []:
                for i in result:
                    print(i)
                self.pushButton.setEnabled(True)

            else:
                print("No match")
                self.pushButton.setEnabled(True)
        self.treeView.setFilter(result)
Exemple #23
0
class FileBrowserWidget(QWidget):
    on_open = pyqtSignal(str)

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

    def initUI(self):
        self.model = QFileSystemModel()
        self.rootFolder = ''
        self.model.setRootPath(self.rootFolder)
        self.tree = QTreeView()
        self.tree.setModel(self.model)

        self.tree.setAnimated(False)
        self.tree.setIndentation(20)
        self.tree.setSortingEnabled(True)
        self.tree.sortByColumn(0, 0)
        self.tree.setColumnWidth(0, 200)
        self.tree.setDragEnabled(True)

        self.tree.setWindowTitle("Dir View")
        self.tree.resize(640, 480)
        self.tree.doubleClicked.connect(self.onDblClick)
        self.tree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.tree.customContextMenuRequested.connect(
            self.onCustomContextMenuRequested)

        windowLayout = QVBoxLayout()
        windowLayout.addWidget(self.tree)
        windowLayout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(windowLayout)

    def onCustomContextMenuRequested(self, point):
        index = self.tree.indexAt(point)
        selectedFile = None
        selectedFolder = None
        ctx = QMenu("Context menu", self)
        if index.isValid():
            file = self.model.fileInfo(index)
            selectedFile = file.absoluteFilePath()
            selectedFolder = selectedFile if file.isDir(
            ) else file.absolutePath()
            if file.isDir():
                ctx.addAction(
                    "Open in file manager", lambda: QDesktopServices.openUrl(
                        QUrl.fromLocalFile(selectedFile)))
            if not file.isDir():
                for wndTyp, meta in WindowTypes.types:
                    text = 'Open with ' + meta.get('displayName', meta['name'])
                    print(wndTyp, meta)
                    ctx.addAction(
                        QAction(text,
                                self,
                                statusTip=text,
                                triggered=lambda dummy, meta=meta: navigate(
                                    "WINDOW", "Type=" + meta['name'],
                                    "FileName=" + selectedFile)))
                ctx.addSeparator()

        ctx.addAction("Set root folder ...",
                      lambda: self.selectRootFolder(preselect=selectedFolder))
        ctx.exec(self.tree.viewport().mapToGlobal(point))

    def selectRootFolder(self, preselect=None):
        if preselect == None: preselect = self.rootFolder
        dir = QFileDialog.getExistingDirectory(self, "Set root folder",
                                               preselect)
        if dir != None:
            self.setRoot(dir)

    def setRoot(self, dir):
        self.rootFolder = dir
        self.model.setRootPath(dir)
        self.tree.setRootIndex(self.model.index(dir))

    def onDblClick(self, index):
        if index.isValid():
            file = self.model.fileInfo(index)
            if not file.isDir():
                navigate("OPEN", "FileName=" + file.absoluteFilePath())

    def saveState(self):
        if self.tree.currentIndex().isValid():
            info = self.model.fileInfo(self.tree.currentIndex())
            return {"sel": info.absoluteFilePath(), "root": self.rootFolder}

    def restoreState(self, state):
        try:
            self.setRoot(state["root"])
        except:
            pass
        try:
            idx = self.model.index(state["sel"])
            if idx.isValid():
                self.tree.expand(idx)
                self.tree.setCurrentIndex(idx)
                self.tree.scrollTo(idx, QAbstractItemView.PositionAtCenter)
        except:
            pass
Exemple #24
0
class AssetBrowser(QMainWindow, Ui_MainWindow, PlaygroundModule):
    Name = "asset_browser"

    def __init__(self, module_manager):
        super(AssetBrowser, self).__init__()
        self.setupUi(self)

        self.init_module(module_manager)

        self.dir_model = QFileSystemModel()
        self.dir_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)
        self.dir_model.setReadOnly(False)

        self.dir_view.setModel(self.dir_model)
        self.dir_view.hideColumn(1)
        self.dir_view.hideColumn(2)
        self.dir_view.hideColumn(3)

        self.file_model = QFileSystemModel()
        self.file_model.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.file_model.setReadOnly(False)

        self.file_view.setModel(self.file_model)

        self.dock = self.modules_manager.new_docked(self, self.Name, "Asset browser",
                                                    Qt.BottomDockWidgetArea)

        self.modules_manager.main_window.splitDockWidget(self.dock,
                                                         self.modules_manager["asset_view"].dock, Qt.Horizontal)

    def on_open_project(self, project):
        project_dir = project.project_dir
        path = os.path.join(project_dir)

        self.dir_model.setRootPath(path)
        self.file_model.setRootPath(path)

        self.dir_view.setRootIndex(self.dir_model.index(path))
        self.file_view.setRootIndex(self.file_model.index(path))

    def dir_clicked(self, idx):
        path = self.dir_model.fileInfo(idx).absoluteFilePath()

        self.file_view.setRootIndex(self.file_model.setRootPath(path))

    def file_doubleclicked(self, idx):
        fileinfo = self.file_model.fileInfo(idx)

        path = fileinfo.absoluteFilePath()
        ext = fileinfo.suffix()
        asset_name = path.replace(self.project_manager.project_dir, '').replace('/src/', '').split('.')[0]

        self.modules_manager.open_asset(path, asset_name, ext)

    def file_clicked(self, idx):
        fileinfo = self.file_model.fileInfo(idx)

        path = fileinfo.absoluteFilePath()
        ext = fileinfo.suffix()
        asset_name = path.replace(self.project_manager.project_dir, '').replace('/src/', '').split('.')[0]

        self.modules_manager.show_asset(path, asset_name, ext)
Exemple #25
0
class MainWindow(QMainWindow):
    inputReceived = pyqtSignal(str)

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # Left Browser tabs
        self.ui.tabWidgetBrowser.removeTab(1)
        self.ui.tabWidgetBrowser.removeTab(1)
        self.ui.tabWidgetBrowser.setTabsClosable(True)
        self.ui.tabWidgetBrowser.tabCloseRequested.connect(self.closeBrowserTab)
        self.ui.tabWidgetBrowser.tabBarDoubleClicked.connect(lambda: self.maximizeTabs(self.ui.tabWidgetBrowser))

        # Left tree views
        self.fileTreeModel = QFileSystemModel(self)
        self.fileTreeModel.setRootPath(QDir.currentPath() + QDir.separator() + 'test')
        self.ui.treeViewFile.setModel(self.fileTreeModel)
        self.ui.treeViewFile.setRootIndex(self.fileTreeModel.index(QDir.currentPath() + QDir.separator() + 'test'))
        self.ui.treeViewFile.hideColumn(1)
        self.ui.treeViewFile.hideColumn(2)
        self.ui.treeViewFile.hideColumn(3)
        self.ui.treeViewFile.doubleClicked.connect(self.openFileFromTree)

        self.ui.treeViewFile.setAnimated(True)
        self.ui.treeViewSyntax.setAnimated(True)
        self.ui.treeViewToken.setAnimated(True)

        self.ui.treeViewFile.setHeaderHidden(True)
        self.ui.treeViewSyntax.setHeaderHidden(True)
        self.ui.treeViewToken.setHeaderHidden(True)

        # Editor tabs
        self.currentEditor = self.ui.codeEditor
        self.currentEditor.file = None
        self.currentEditorTab = self.ui.tabEditor
        self.openedEditors = [self.currentEditor]
        self.openedEditorTabs = [self.currentEditorTab]
        self.currentEditor.setFocus()  # set focus
        self.ui.tabWidgetEditor.tabCloseRequested.connect(self.closeEditorTab)
        self.ui.tabWidgetEditor.tabBarClicked.connect(self.switchEditorTab)
        self.ui.tabWidgetEditor.tabBarDoubleClicked.connect(lambda: self.maximizeTabs(self.ui.tabWidgetEditor))

        # Bottom console
        font = QFont()
        font.setFamily("Courier")
        font.setStyleHint(QFont.Monospace)
        font.setFixedPitch(True)
        font.setPointSize(10)
        self.ui.console.setFont(font)
        self.ui.console.setReadOnly(True)
        self.waitInputCond = QWaitCondition()
        self.oldConsoleText = None

        # Bottom output tabs
        self.ui.tabWidgetOutput.hide()
        self.ui.tabWidgetOutput.tabCloseRequested.connect(self.closeOutputTab)
        self.ui.tabWidgetOutput.tabBarDoubleClicked.connect(lambda: self.maximizeTabs(self.ui.tabWidgetOutput))
        self.ui.tabWidgetOutput.setTabText(0, 'Console')

        # Previous opened tabs,for maximizing
        self.preOpenedTabs = None

        # Initial size of inner splitter
        self.ui.splitterInner.setSizes([180, 459 * 2 - 180])

        # Menu "File"
        self.ui.actionOpen.triggered.connect(self.openFile)
        self.ui.actionNew.triggered.connect(self.newFile)
        self.ui.actionSave.triggered.connect(self.saveFile)
        self.ui.actionSaveAs.triggered.connect(self.saveFileAs)
        self.ui.actionQuit.triggered.connect(self.close)

        # Menu "Edit"
        self.connectMenuEditSlots()

        # Menu "View"
        self.ui.menuView.triggered.connect(self.manageMenuView)
        self.ui.actionAboutQt.triggered.connect(QApplication.aboutQt)

        # Menu "Run"
        self.ui.actionRun.triggered.connect(self.run)
        self.ui.actionBuild.triggered.connect(self.runCompile)
        self.ui.actionShowStable.triggered.connect(self.runSemantic)
        self.ui.actionRunParser.triggered.connect(self.runParser)
        self.ui.actionRunLexer.triggered.connect(self.runLexer)

    @pyqtSlot(bool)
    def runLexer(self, checked):
        """
        Run lexer and present result on self.ui.tabToken Tree
        :return:
        """
        p = self.genParser(Parser.mode_lexer)
        tokenNode = p.lexse() if p else None
        if not tokenNode:
            self.endEcho(False)
            return

        self.showBrowserTree(self.ui.tabToken, tokenNode)
        self.endEcho(True)

    @pyqtSlot(bool)
    def runParser(self, checked):
        """
        Run parser and present result on self.ui.tabSyntax Tree
        :return:
        """
        # Begin parse
        p = self.genParser(Parser.mode_parser)
        result = p.parse() if p else None
        if not result:
            self.endEcho(False)
            return

        syntaxNode, tokenNode = result

        # self.showBrowserTree(self.ui.tabToken, tokenNode)
        self.ui.treeViewToken.setModel(TreeModel(tokenNode))
        self.showBrowserTree(self.ui.tabSyntax, syntaxNode)
        self.endEcho(True)

    @pyqtSlot(bool)
    def runSemantic(self, checked):
        """
        run semantics analysing and print symbol table
        :return:
        """
        p = self.genParser(Parser.mode_stable)
        result = p.semantic() if p else None
        if not result:
            self.endEcho(False)
            return

        stable, syntaxNode, tokenNode = result

        self.ui.treeViewToken.setModel(TreeModel(tokenNode))
        self.ui.treeViewSyntax.setModel(TreeModel(syntaxNode))
        self.endEcho(True)

    @pyqtSlot(bool)
    def runCompile(self, checked):
        """
        Run compiler and print Intermediate code
        :return:
        """
        p = self.genParser(Parser.mode_compile)
        result = p.compile() if p else None
        if not result:
            self.endEcho(False)
            return

        codes, stable, syntaxNode, tokenNode = result
        self.ui.treeViewToken.setModel(TreeModel(tokenNode))
        self.ui.treeViewSyntax.setModel(TreeModel(syntaxNode))
        self.endEcho(True)

    @pyqtSlot(bool)
    def run(self, checked):
        """
        compile and run the source code

        compile in main thread and run in a worker thread
        """
        p = self.genParser(Parser.mode_execute)
        result = p.compile() if p else None
        if not result:
            self.endEcho(False)
            return

        codes, stable, syntaxNode, tokenNode = result
        self.ui.treeViewToken.setModel(TreeModel(tokenNode))
        self.ui.treeViewSyntax.setModel(TreeModel(syntaxNode))

        console = Console(self.ui.console, parent=self, waitCond=self.waitInputCond)
        console.update.connect(self.updateOutput)
        self.inputReceived.connect(console.receivedInput)
        self.ui.console.blockCountChanged.connect(self.waitInput)
        self.ui.console.textChanged.connect(self.disableBack)

        interp = Interpreter(codes, stdin=console, stdout=console, stderr=console)
        thread = ExecuteThread(interp.inter, self)
        thread.start()

    def genParser(self, mode=Parser.mode_execute):
        """
        Generate a parser instance
        :param mode:
        :return:
        """
        if not self.saveFile():
            return
        self.showOutputPanel()
        self.ui.actionViewConsole.setChecked(True)
        self.beginEcho()

        stdin = open(self.currentEditor.file, 'r')
        console = Console(self.ui.console, parent=self)
        console.update.connect(self.updateOutput)

        return Parser(stdin, stdout=console, stderr=console, mode=mode)

    def beginEcho(self):
        self.updateOutput('%s\n' % self.currentEditor.file)

    def endEcho(self, success=True):
        msg = 'successfully' if success else 'unsuccessfully'
        self.updateOutput('Process finished %s\n' % msg)

    @pyqtSlot(str)
    def updateOutput(self, content):
        """
        Update bottom text browser when content is writen to it.
        :param content:
        :return:
        """
        self.ui.console.moveCursor(QTextCursor.End)
        self.ui.console.insertPlainText('%s' % content)
        self.oldConsoleText = self.ui.console.toPlainText()

    @pyqtSlot(int)
    def waitInput(self, newBlockCount):
        """
        :param newBlockCount: line count
        :return:
        """
        if not self.ui.console.isReadOnly():
            self.inputReceived.emit(self.ui.console.toPlainText()
                                    .replace(self.oldConsoleText, ''))
            self.waitInputCond.wakeAll()
            self.ui.console.setReadOnly(True)

    @pyqtSlot()
    def disableBack(self):
        """
        disable backspace when waiting for input
        :return:
        """
        if not self.ui.console.isReadOnly():
            if len(self.oldConsoleText) > len(self.ui.console.toPlainText()):
                self.ui.console.setPlainText(self.oldConsoleText)
                self.ui.console.moveCursor(QTextCursor.End)

    def closeEvent(self, event):
        """
        Override. When Close Event Triggered.
        Ask user for saving modified files
        :param event:
        :return:
        """
        for i in range(len(self.openedEditors)):
            editor = self.openedEditors[i]
            editorTab = self.openedEditorTabs[i]
            if editor.document().isModified():
                name = ntpath.basename(editor.file) if editor.file else 'New File'
                ret = QMessageBox.warning(
                        self, name,
                        'The document has been modified.\nDo you want to save your changes?',
                        QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
                if ret == QMessageBox.Save:
                    event.accept() if self.saveFile() else event.ignore()
                elif ret == QMessageBox.Discard:
                    index = self.ui.tabWidgetEditor.indexOf(editorTab)
                    self.ui.tabWidgetEditor.removeTab(index)
                    event.accept()
                else:
                    event.ignore()

    def showOutputPanel(self):
        """
        Clear previous output and show the ouput panel
        :return:
        """
        self.ui.console.clear()
        self.ui.tabWidgetOutput.show()

    def showBrowserTree(self, tab, rootNode):
        """
        Show treeView on tabWidgetBrowser
        :param tab:
        :param rootNode:
        """
        model = TreeModel(rootNode)

        if tab == self.ui.tabSyntax:
            treeView = self.ui.treeViewSyntax
            name = 'Syntax'
            self.ui.actionViewSystaxTree.setChecked(True)
        else:
            treeView = self.ui.treeViewToken
            name = 'Token'
            self.ui.actionViewTokenTree.setChecked(True)

        treeView.setModel(model)

        # show the tab
        index = self.ui.tabWidgetBrowser.indexOf(tab)
        if index == -1:
            self.ui.tabWidgetBrowser.addTab(tab, name)
            index = self.ui.tabWidgetBrowser.indexOf(tab)
        self.ui.tabWidgetBrowser.setCurrentIndex(index)

        self.addjustBrowserWidth()

    def connectMenuEditSlots(self):
        """
        set menu "Edit" signals connect to current editor slots
        :return:
        """
        self.ui.actionCopy.triggered.connect(self.currentEditor.copy)
        self.ui.actionCut.triggered.connect(self.currentEditor.cut)
        self.ui.actionPaste.triggered.connect(self.currentEditor.paste)
        self.ui.actionUndo.triggered.connect(self.currentEditor.undo)
        self.ui.actionRedo.triggered.connect(self.currentEditor.redo)
        self.ui.actionSelectAll.triggered.connect(self.currentEditor.selectAll)

    def disconnectMenuEditSlots(self):
        """
        disconnect menu "Edit" signals
        :return:
        """
        self.ui.actionCopy.triggered.disconnect(self.currentEditor.copy)
        self.ui.actionCut.triggered.disconnect(self.currentEditor.cut)
        self.ui.actionPaste.triggered.disconnect(self.currentEditor.paste)
        self.ui.actionUndo.triggered.disconnect(self.currentEditor.undo)
        self.ui.actionRedo.triggered.disconnect(self.currentEditor.redo)
        self.ui.actionSelectAll.triggered.disconnect(self.currentEditor.selectAll)

    def createEditorTab(self):
        """
        Create a new Editor tab and set as current editor
        Should reconnect the signal on menu 'Edit' actions
        :return:
        """
        # add a new editor
        self.currentEditorTab = QtWidgets.QWidget()
        horizontalLayout = QtWidgets.QHBoxLayout(self.currentEditorTab)
        horizontalLayout.setContentsMargins(0, 0, 0, 0)
        horizontalLayout.setSpacing(6)
        codeEditor = CodeEditor(self.currentEditorTab)
        horizontalLayout.addWidget(codeEditor)
        self.ui.tabWidgetEditor.addTab(self.currentEditorTab, "")

        # disconnect signals
        self.disconnectMenuEditSlots()

        # change current tab and editors
        self.currentEditor = codeEditor
        self.currentEditor.file = None
        self.openedEditors.append(self.currentEditor)
        self.openedEditorTabs.append(self.currentEditorTab)

        # connect signals
        self.connectMenuEditSlots()

        # set tab closeable
        if len(self.openedEditorTabs) > 1:
            self.ui.tabWidgetEditor.setTabsClosable(True)

    @pyqtSlot(int)
    def switchEditorTab(self, index):
        """
        Switch current active editor tab to index
        Should reconnect the signal on menu 'Edit' actions
        :param index:
        :return:
        """
        self.disconnectMenuEditSlots()
        self.currentEditorTab = self.openedEditorTabs[index]
        self.currentEditor = self.openedEditors[index]
        self.connectMenuEditSlots()

    @pyqtSlot(int)
    def closeEditorTab(self, index):
        """
        Triggered when closing the editor tab at index requested
        :param index:
        :return:
        """
        self.ui.tabWidgetEditor.removeTab(index)
        self.openedEditorTabs.pop(index)
        self.openedEditors.pop(index)
        self.switchEditorTab(0)  # choose the beginning tab as current active
        if len(self.openedEditorTabs) == 1:
            self.ui.tabWidgetEditor.setTabsClosable(False)

    @pyqtSlot(int)
    def closeBrowserTab(self, index):
        """
        Close Left Browser Tab at index
        :param index:
        :return:
        """
        # make menu "View" corresponding
        w = self.ui.tabWidgetBrowser.widget(index)
        if w == self.ui.tabFile:
            self.ui.actionViewFiles.setChecked(False)
        elif w == self.ui.tabToken:
            self.ui.actionViewTokenTree.setChecked(False)
        else:
            self.ui.actionViewSystaxTree.setChecked(False)

        # remove tab
        self.ui.tabWidgetBrowser.removeTab(index)
        if self.ui.tabWidgetBrowser.count() == 0:
            self.ui.tabWidgetBrowser.hide()

    @pyqtSlot(int)
    def closeOutputTab(self, index):
        """
        Close(hide) the output tab widget
        :param index:
        """

        # make menu "View" corresponding
        self.ui.actionViewConsole.setChecked(False)

        self.ui.tabWidgetOutput.hide()

    def recoverTabWidgets(self):
        """
        recover tabs when cancel maximizing
        :return:
        """
        for tab in self.preOpenedTabs:
            tab.show()
        self.preOpenedTabs = None

    def storeOpenedTabs(self):
        """
        store tabs opened before maximize
        :return:
        """
        self.preOpenedTabs = []
        if not self.ui.tabWidgetOutput.isHidden():
            self.preOpenedTabs.append(self.ui.tabWidgetOutput)
        if not self.ui.tabWidgetEditor.isHidden():
            self.preOpenedTabs.append(self.ui.tabWidgetEditor)
        if not self.ui.tabWidgetBrowser.isHidden():
            self.preOpenedTabs.append(self.ui.tabWidgetBrowser)

    def maximizeTabs(self, widget):
        if self.preOpenedTabs:
            self.recoverTabWidgets()
        else:
            self.storeOpenedTabs()
            for w in [self.ui.tabWidgetBrowser, self.ui.tabWidgetOutput, self.ui.tabWidgetEditor]:
                if w != widget:
                    w.hide()

    @pyqtSlot(QAction)
    def manageMenuView(self, action):
        """
        Handle the action on menu "View"
        :param action:
        :return:
        """
        if action == self.ui.actionViewToolbar:
            self.ui.toolBar.show() if action.isChecked() else self.ui.toolBar.hide()
            return

        pair = {
            self.ui.actionViewFiles: (self.ui.tabWidgetBrowser, self.ui.tabFile, 'File'),
            self.ui.actionViewTokenTree: (self.ui.tabWidgetBrowser, self.ui.tabToken, 'Token'),
            self.ui.actionViewSystaxTree: (self.ui.tabWidgetBrowser, self.ui.tabSyntax, 'Syntax'),
            self.ui.actionViewConsole: (self.ui.tabWidgetOutput, self.ui.tabConsole, 'Console'),
        }
        p = pair[action]
        widget = p[0]
        tab = p[1]
        name = p[2]

        if action.isChecked():
            widget.addTab(tab, name)
            widget.setCurrentWidget(tab)

            if widget == self.ui.tabWidgetBrowser:  # reset tab inner splitter size
                self.addjustBrowserWidth()

            if widget.isHidden():
                widget.show()
        else:
            widget.removeTab(
                    widget.indexOf(tab))
            if widget.count() == 0:
                widget.hide()

    def addjustBrowserWidth(self):
        w = self.ui.tabWidgetBrowser.count() * 80
        self.ui.splitterInner.setSizes([w, self.ui.splitterInner.width() - w])

    @pyqtSlot(bool)
    def openFile(self, checked=True, path=None):
        """
        Open a new file.
        If current editor is associated with a file or its content is not null,
        Then create a new editor tab
        :return:
        """
        path = QFileDialog.getOpenFileName()[0] if not path else path
        if len(path) != 0:
            qfile = QFile(path)
            if not qfile.open(QFile.ReadOnly or QFile.Text):
                QMessageBox.warning(self, 'Application',
                                    'Cannot read file %s:\n%s.' % (path, qfile.errorString()))
                return
            with open(path, 'r') as _file:
                content = _file.read()

            if self.currentEditor.file or len(self.currentEditor.document().toPlainText()) > 0:
                self.createEditorTab()

            # associate file on disk with editor
            self.currentEditor.file = path

            # update tab name
            index = self.ui.tabWidgetEditor.indexOf(self.currentEditorTab)
            _translate = QCoreApplication.translate
            self.ui.tabWidgetEditor.setTabText(
                    index, _translate("MainWindow", ntpath.basename(path)))
            self.ui.tabWidgetEditor.setCurrentIndex(index)
            self.currentEditor.setPlainText(content)

    @pyqtSlot(int)
    def openFileFromTree(self, index):
        f = self.fileTreeModel.fileInfo(index)
        if f.isFile():
            self.openFile(path=f.filePath())

    @pyqtSlot(bool)
    def newFile(self, checked):
        """
        create a new editor tab
        :param action:
        :return:
        """
        self.createEditorTab()
        index = self.ui.tabWidgetEditor.indexOf(self.currentEditorTab)
        _translate = QCoreApplication.translate
        self.ui.tabWidgetEditor.setTabText(
                index, _translate("MainWindow", 'New File'))
        self.ui.tabWidgetEditor.setCurrentIndex(index)

    @pyqtSlot(bool)
    def saveFile(self, checked=None):
        """
        Save file.
        If current editor is associated with a file on the disk,
        then save it. Or save file as...
        :param checked:
        :return: Saved or canceled
        """
        if self.currentEditor.file:
            if self.currentEditor.document().isModified():
                with open(self.currentEditor.file, 'w') as f:
                    f.write(self.currentEditor.document().toPlainText())
                self.currentEditor.document().setModified(False)
            return True
        else:
            return self.saveFileAs()

    @pyqtSlot(bool)
    def saveFileAs(self, checked=None):
        """
        Save File As...
        :param checked:
        :return: If saved or canceled
        """
        dialog = QFileDialog()
        dialog.setWindowModality(Qt.WindowModal)
        dialog.setAcceptMode(QFileDialog.AcceptSave)
        if dialog.exec_():
            filepath = dialog.selectedFiles()[0]
            with open(filepath, 'w') as f:
                f.write(self.currentEditor.document().toPlainText())
            self.currentEditor.document().setModified(False)
            self.currentEditor.file = filepath
            return True
        else:
            return False
class Explorer(QWidget):
    def __init__(self, rootdir=QDir.rootPath()):
        QWidget.__init__(self)
        self.treeview = QTreeView()
        self.listview = QListView()
        self.path = rootdir
        self.filename = ''
        self.filepath = rootdir
        self.canvas = None
        self.col_selector = None

        self.header = ''
        self.xcol = [1]
        self.ycol = [1]
        self.ncols = 0

        self.dirModel = QFileSystemModel()
        self.dirModel.setRootPath(self.path)
        self.dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)

        self.fileModel = QFileSystemModel()
        self.fileModel.setRootPath(self.filepath)
        self.fileModel.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.fileModel.setNameFilters(['*.txt'])
        self.fileModel.setNameFilterDisables(0)

        self.treeview.setModel(self.dirModel)
        self.listview.setModel(self.fileModel)
        for i in [1, 2, 3]: self.treeview.setColumnHidden(i, True)
        self.treeview.setHeaderHidden(True)

        self.treeview.setRootIndex(self.dirModel.index(self.path))
        self.listview.setRootIndex(self.fileModel.index(self.path))

        self.treeview.clicked.connect(self.on_clicked)
        self.listview.selectionModel().currentChanged.connect(self.file_selected)
        self.listview.selectionModel().currentChanged.connect(lambda: self.canvas.update_plot(self))
        self.listview.selectionModel().currentChanged.connect(lambda: self.col_selector.update_range(self.ncols))

    def on_clicked(self, index):
        self.path = self.dirModel.fileInfo(index).absoluteFilePath()
        self.listview.setRootIndex(self.fileModel.setRootPath(self.path))

    def file_selected(self, index):
        self.filename = self.fileModel.fileName(index)
        self.filepath = self.fileModel.filePath(index)
        self.load_file()

    def load_file(self):
        try:
            if self.filepath.endswith('.txt'):
                with open(self.filepath, 'r') as file:
                        self.header, self.xcol, self.ycol = '', [], []
                        for ln in file:
                            if ln.startswith('#'):
                                self.header += ln[2:]
                            else:
                                cols = ln.split('\t')
                                self.xcol.append(float(cols[0]))
                                self.ycol.append(float(cols[self.col_selector.sp.value()]))
                        self.ncols = len(cols)
                        self.col_selector.update_range(self.ncols)
        except:
            self.header, self.xcol, self.ycol = '', [0], [0]

    def update_rootdir(self, rootdir):
        self.path = rootdir
        self.treeview.setRootIndex(self.dirModel.index(self.path))
        self.listview.setRootIndex(self.fileModel.index(self.path))
class Chapterize(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_ChapterizeWindow()
        self.ui.setupUi(self)

        self.dir = QDir.homePath()

        self.chaptersTableModel = ChaptersTableModel()
        self.ui.chapterTable.setModel(self.chaptersTableModel)
        self.ui.chapterTable.setItemDelegate(TimestampDelegate())

        self.ui.chapterTable.contextMenuEvent = self.onChapterContextMenu

        self.mp3ListModel = QFileSystemModel()
        self.mp3ListModel.setNameFilters(['*.mp3'])
        self.mp3ListModel.setFilter(QDir.Files)
        self.mp3ListModel.setRootPath(self.dir)
        self.mp3ListModel.setNameFilterDisables(False)

        self.ui.mp3List.setModel(self.mp3ListModel)
        self.ui.mp3List.setRootIndex(self.mp3ListModel.index(self.dir))
        self.ui.mp3List.selectionModel().selectionChanged.connect(self.onMp3Select)

        self.ui.actionChangeDir.triggered.connect(self.onDirectoryChange)
        self.ui.actionExit.triggered.connect(self.close)
        self.ui.actionSave.triggered.connect(self.chaptersTableModel.save)

    @pyqtSlot()
    def onDirectoryChange(self):
        chosen_dir = QFileDialog.getExistingDirectory(self, "Change Directory...", self.dir, QFileDialog.ShowDirsOnly)
        if chosen_dir != '':
            self.dir = chosen_dir
            self.mp3ListModel.setRootPath(self.dir)
            self.ui.mp3List.setRootIndex(self.mp3ListModel.index(self.dir))

    @pyqtSlot(QItemSelection, QItemSelection)
    def onMp3Select(self, selected, deselected):
        sel_idx = selected.indexes()[0]
        pth = self.mp3ListModel.fileInfo(sel_idx).absoluteFilePath()
        self.chaptersTableModel.set_file(pth)

    @pyqtSlot(QContextMenuEvent)
    def onChapterContextMenu(self, e):
        idx = self.ui.chapterTable.indexAt(e.pos())
        row = idx.row()
        if row < 0:
            row = self.chaptersTableModel.rowCount()

        menu = QMenu(self)

        insertAction = QAction('&Insert', menu)
        insertAction.triggered.connect(lambda: self.chaptersTableModel.insertRow(row))

        menu.addAction(insertAction)

        deleteAction = QAction('&Delete', menu)
        deleteAction.triggered.connect(lambda: self.chaptersTableModel.removeRow(row))

        menu.addAction(deleteAction)

        menu.exec_(e.globalPos())
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(874, 596)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(MainWindow)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.horizontalLayout.addWidget(self.centralwidget)
        self.frame = QtWidgets.QFrame(self.centralwidget)
        self.frame.setGeometry(QtCore.QRect(0, 0, 871, 41))
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.frame.setObjectName("frame")
        self.line = QtWidgets.QFrame(self.frame)
        self.line.setGeometry(QtCore.QRect(43, 0, 20, 41))
        self.line.setFrameShape(QtWidgets.QFrame.VLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")
        self.line_2 = QtWidgets.QFrame(self.frame)
        self.line_2.setGeometry(QtCore.QRect(180, 0, 20, 41))
        self.line_2.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_2.setObjectName("line_2")
        self.widget = QtWidgets.QWidget(self.centralwidget)
        self.widget.setGeometry(QtCore.QRect(0, 40, 221, 541))
        self.widget.setObjectName("widget")
        self.label = QtWidgets.QLabel(self.widget)
        self.label.setGeometry(QtCore.QRect(10, 10, 191, 16))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.widget)
        self.label_2.setGeometry(QtCore.QRect(10, 70, 201, 16))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.widget)
        self.label_3.setGeometry(QtCore.QRect(10, 140, 191, 16))
        self.label_3.setObjectName("label_3")
        self.groupBox = QtWidgets.QGroupBox(self.widget)
        self.groupBox.setGeometry(QtCore.QRect(10, 250, 201, 141))
        self.groupBox.setObjectName("groupBox")
        self.checkBox = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox.setGeometry(QtCore.QRect(10, 20, 70, 17))
        self.checkBox.setShortcut("")
        self.checkBox.setTristate(False)
        self.checkBox.setObjectName("checkBox")
        self.checkBox_2 = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_2.setGeometry(QtCore.QRect(10, 50, 70, 17))
        self.checkBox_2.setObjectName("checkBox_2")
        self.checkBox_3 = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_3.setGeometry(QtCore.QRect(10, 80, 70, 17))
        self.checkBox_3.setObjectName("checkBox_3")
        self.checkBox_4 = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_4.setGeometry(QtCore.QRect(10, 110, 111, 17))
        self.checkBox_4.setObjectName("checkBox_4")
        self.pushButton = QtWidgets.QPushButton(self.widget)
        self.pushButton.setGeometry(QtCore.QRect(10, 200, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.widget)
        self.pushButton_2.setGeometry(QtCore.QRect(100, 200, 75, 23))
        self.pushButton_2.setObjectName("pushButton_2")

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 874, 21))
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.menuEdit = QtWidgets.QMenu(self.menubar)
        self.menuEdit.setObjectName("menuEdit")
        self.menuTools = QtWidgets.QMenu(self.menubar)
        self.menuTools.setObjectName("menuTools")
        self.menuHelp = QtWidgets.QMenu(self.menubar)
        self.menuHelp.setObjectName("menuHelp")
        MainWindow.setMenuBar(self.menubar)
        self.actionAbout = QtWidgets.QAction(MainWindow)
        self.actionAbout.setObjectName("actionAbout")
        self.actionOpen = QtWidgets.QAction(MainWindow)
        self.actionOpen.setObjectName("actionOpen")
        self.actionSearch_From_Specific_Location = QtWidgets.QAction(
            MainWindow)
        self.actionSearch_From_Specific_Location.setObjectName(
            "actionSearch_From_Specific_Location")
        self.actionDelete = QtWidgets.QAction(MainWindow)
        self.actionDelete.setObjectName("actionDelete")
        self.actionExit = QtWidgets.QAction(MainWindow)
        self.actionExit.setObjectName("actionExit")
        self.actionCut = QtWidgets.QAction(MainWindow)
        self.actionCut.setObjectName("actionCut")
        self.actionCopy = QtWidgets.QAction(MainWindow)
        self.actionCopy.setObjectName("actionCopy")
        self.actionClear_List = QtWidgets.QAction(MainWindow)
        self.actionClear_List.setObjectName("actionClear_List")
        self.actionSelect_All = QtWidgets.QAction(MainWindow)
        self.actionSelect_All.setObjectName("actionSelect_All")
        self.actionProperties = QtWidgets.QAction(MainWindow)
        self.actionProperties.setObjectName("actionProperties")
        self.menuFile.addAction(self.actionOpen)
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionSearch_From_Specific_Location)
        self.menuFile.addAction(self.actionDelete)
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionExit)
        self.menuEdit.addAction(self.actionCut)
        self.menuEdit.addAction(self.actionCopy)
        self.menuEdit.addSeparator()
        self.menuEdit.addAction(self.actionClear_List)
        self.menuEdit.addAction(self.actionSelect_All)
        self.menuTools.addAction(self.actionProperties)
        self.menuTools.addSeparator()
        self.menuHelp.addAction(self.actionAbout)
        self.menuHelp.addSeparator()
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuEdit.menuAction())
        self.menubar.addAction(self.menuTools.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())

        #Search column View
        #self.columnView = QtWidgets.QColumnView(self.centralwidget)
        #self.columnView.setGeometry(QtCore.QRect(220, 50, 651, 521))
        #self.columnView.setResizeGripsVisible(True)
        #self.columnView.setObjectName("columnView")
        self.treeView = QtWidgets.QTreeView(self.centralwidget)
        self.treeView.setGeometry(QtCore.QRect(220, 50, 651, 521))

        self.treeView.setObjectName("columnView")
        self.horizontalLayout.addWidget(self.treeView)
        path = QDir.rootPath()

        self.dirModel = QFileSystemModel()
        self.dirModel.setRootPath(QDir.rootPath())

        self.fileModel = QFileSystemModel()
        self.fileModel.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.model = QtWidgets.QFileSystemModel()
        self.model.setRootPath((QtCore.QDir.rootPath()))
        self.treeView.setModel(self.model)
        self.treeView.setRootIndex(self.dirModel.index(path))
        self.treeView.doubleClicked.connect(self.on_clicked)
        self.treeView.setObjectName("treeView")
        self.treeView.setColumnWidth(0, 300)

        logoPath = QDir.homePath()
        self.logoModel = QFileSystemModel()
        self.logoModel.setRootPath(logoPath)
        self.logoModel.setFilter(QDir.NoDotAndDotDot | QDir.Files
                                 | QDir.NoSymLinks)
        print(logoPath)

        self.comboBox = QtWidgets.QComboBox(self.widget)
        self.comboBox.setGeometry(QtCore.QRect(10, 30, 201, 31))
        self.comboBox.setEditable(True)
        self.comboBox.setObjectName("comboBox")
        self.comboBox_2 = QtWidgets.QComboBox(self.widget)
        self.comboBox_2.setGeometry(QtCore.QRect(10, 100, 201, 31))
        self.comboBox_2.setEditable(True)
        self.comboBox_2.setObjectName("comboBox_2")
        self.comboBox_3 = QtWidgets.QComboBox(self.widget)
        self.comboBox_3.setGeometry(QtCore.QRect(10, 160, 201, 31))
        self.comboBox_3.setEditable(True)
        self.comboBox_3.setObjectName("comboBox_3")
        self.comboBox_3.setModel(self.logoModel)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(
            _translate("MainWindow", "Search for files or folders"))
        self.label_2.setText(
            _translate("MainWindow",
                       "Containing text (for wordprocessor files)"))
        self.label_3.setText(_translate("MainWindow", "Look in (Directory)"))
        self.groupBox.setTitle(_translate("MainWindow", "Options"))
        self.checkBox.setText(_translate("MainWindow", "Date"))
        self.checkBox_2.setText(_translate("MainWindow", "Size"))
        self.checkBox_3.setText(_translate("MainWindow", "Type"))
        self.checkBox_4.setText(_translate("MainWindow", "Advance Options"))

        self.pushButton.setText(_translate("MainWindow", "Search"))
        self.pushButton.clicked.connect(self.search)
        self.pushButton_2.setText(_translate("MainWindow", "Stop"))
        self.pushButton_2.clicked.connect(self.stop)

        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.menuEdit.setTitle(_translate("MainWindow", "Edit"))
        self.menuTools.setTitle(_translate("MainWindow", "Tools"))
        self.menuHelp.setTitle(_translate("MainWindow", "Help"))
        self.actionAbout.setText(_translate("MainWindow", "About"))
        self.actionOpen.setText(_translate("MainWindow", "Open"))
        self.actionSearch_From_Specific_Location.setText(
            _translate("MainWindow", "Search From Specific Location"))
        self.actionDelete.setText(_translate("MainWindow", "Delete"))
        self.actionExit.setText(_translate("MainWindow", "Exit"))
        self.actionCut.setText(_translate("MainWindow", "Cut"))
        self.actionCopy.setText(_translate("MainWindow", "Copy"))
        self.actionClear_List.setText(_translate("MainWindow", "Clear List"))
        self.actionSelect_All.setText(_translate("MainWindow", "Select All"))
        self.actionProperties.setText(_translate("MainWindow", "Properties"))

    def on_clicked(self, index):
        path = self.fileModel.fileInfo(index).absoluteFilePath()
        #Tab Reading for index values
        os.startfile(path)

    def stop(self):
        print("Program Stoped")
        self.pushButton.setEnabled(True)

    def search(self):
        print("Search started")
        self.pushButton.setEnabled(False)
        file_name = self.comboBox.currentText()
        print(file_name)
        path_tmp1 = self.comboBox_3.currentText()
        print(path_tmp1)
        path_tmp = re.findall("[A-Z]:", path_tmp1)
        print(path_tmp[-1])
        cur_dir = path_tmp[-1] + '/' ''
        print(cur_dir)

        result = []
        # Wlaking top-down from the root
        for root, dir, files in os.walk(cur_dir):
            for i in files:
                b = re.findall(".*" + file_name + ".*.*", i, re.IGNORECASE)
                if b == []:
                    pass
                elif b != []:
                    for i in files:
                        if b[-1] == i:
                            result.append(os.path.join(root, b[-1]))
        if result != []:
            for i in result:
                print(i)
            self.pushButton.setEnabled(True)

        else:
            print("No match")
            self.pushButton.setEnabled(True)
Exemple #29
0
class FileWidget(QWidget):
    def __init__(self):
        super().__init__()
        # QWidget部件是PyQt5所有用户界面对象的基类。他为QWidget提供默认构造函数。默认构造函数没有父类。
        # 创建一个文件系统模型
        self.file_model = QFileSystemModel()
        # 设置目录为当前工作目录
        self.file_model.setRootPath(QDir.currentPath())
        # 创建树视图,构建文件目录视图
        self.treeview = QTreeView()
        # 绑定此文件模型
        self.treeview.setModel(self.file_model)
        '''
        设置当前勾结点索引为当前工作目录
        如果想从整个文件系统根节点开始浏览视图,
        简单删掉此行即可
        '''
        self.treeview.setRootIndex(self.file_model.index(QDir.currentPath()))
        # 头部显示排序戳
        self.treeview.header().setSortIndicatorShown(True)

        # 创建右键菜单
        self.treeview.setContextMenuPolicy(Qt.CustomContextMenu)
        # point = self.treeview.pos()
        self.treeview.customContextMenuRequested.connect(self.generateMenu)
        '''
        # 底部按钮布局
        self.mkdirButton = QPushButton("Make Directory...")
        self.rmButton = QPushButton("Remove")
        buttonLayout = QHBoxLayout()
        buttonLayout.addWidget(self.mkdirButton)
        buttonLayout.addWidget(self.rmButton)
        '''
        # 文件管理界面布局
        layout = QVBoxLayout()
        layout.addWidget(self.treeview)
        # layout.addLayout(buttonLayout)

        # resize()方法调整窗口的大小。600px宽300px高
        self.resize(600, 300)
        # move()方法移动窗口在屏幕上的位置到x = 300,y = 300坐标。
        self.move(300, 300)
        # 设置窗口的标题
        self.setWindowTitle('File Manage')
        # 设置窗口的图标
        self.setWindowIcon(QIcon('File-Explorer.png'))
        self.setLayout(layout)

    # 生成右键菜单
    def generateMenu(self, position):
        # 索引默认值
        row_num = -1
        # 遍历确定行号
        for i in self.treeview.selectionModel().selection().indexes():
            row_num = i.row()
        # 保证选中有效项
        if row_num != -1:
            # 创建右键菜单
            menu = QMenu()
            # 提供删除和创建文件/文件夹选项
            item1 = menu.addAction("Delete")
            item2 = menu.addAction("NewDirectory")
            # 在光标处显示执行菜单
            action = menu.exec_(self.treeview.mapToGlobal(position))
            if action == item1:
                #弹出消息框确认此次删除操作
                res = self.msgbox()
                if res:
                    self.delete()
                else:
                    return
            elif action == item2:
                self.mkdirectory()
            else:
                return
        else:
            return

    # 删除选定文件/文件夹
    def delete(self):
        index = self.treeview.currentIndex()
        if index.isValid():
            fileInfo = self.file_model.fileInfo(index)
            if fileInfo.isDir():
                self.file_model.rmdir(index)
            else:
                self.file_model.remove(index)

    # 确认框
    def msgbox(self):
        msgBox = QMessageBox()
        msgBox.setWindowTitle("Warning")
        msgBox.setText("Delete the file/dir you selected?")
        msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        msgBox.setDefaultButton(QMessageBox.No)
        # button = QMessageBox.question("Warning", "delete the file/dir?",
        #                               QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        button = msgBox.exec_()
        if button == QMessageBox.No:
            return False
        elif button == QMessageBox.Yes:
            return True

    # 创建文件夹
    def mkdirectory(self):
        index = self.treeview.rootIndex()
        if index.isValid():
            # 弹出输入框录入文件名
            dirname, ok = QInputDialog.getText(self, "File Name",
                                               "Input an unique dir name:")
            if ok:
                self.file_model.mkdir(index, dirname)
            else:
                return

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_F3:
            self.close()