Exemple #1
0
    def __init__(self, parent):
        super().__init__(parent)
        self.lineNumberArea = QLineNumberArea(self)
        self.blockCountChanged.connect(self.updateLineNumberAreaWidth)
        self.updateRequest.connect(self.updateLineNumberArea)
        self.cursorPositionChanged.connect(self.highlightCurrentLine)
        self.updateLineNumberAreaWidth(0)
        self.parent = parent
        self.font = QFont()
        self.size = 12
        self.dialog = MessageBox(self)
        self.menu_font = QFont()
        self.menu_font.setFamily("Iosevka")
        self.menu_font.setPointSize(10)
        self.font.setFamily(editor["editorFont"])
        self.font.setPointSize(editor["editorFontSize"])
        self.focused = None
        self.text = None
        self.replace_tabs = 4
        self.setWordWrapMode(4)
        self.setFont(self.font)
        self.l = 0
        self.highlightingRules = []
        self.indexes = None

        self.setTabStopWidth(editor["TabWidth"])
        self.createStandardContextMenu()
        self.setWordWrapMode(QTextOption.NoWrap)
Exemple #2
0
 def __init__(self, callback, app=None, palette=None):
     super().__init__()
     directoryFont = QFont()
     self.app = app
     self.palette = palette
     directoryFont.setFamily(editor["directoryFont"])
     directoryFont.setPointSize(editor["directoryFontSize"])
     self.open_callback = callback
     self.setContextMenuPolicy(Qt.CustomContextMenu)
     self.customContextMenuRequested.connect(self.openMenu)
     self.setFont(directoryFont)
     self.layout = QHBoxLayout()
     self.model = QFileSystemModel()
     self.setModel(self.model)
     self.model.setRootPath(QDir.rootPath())
     self.setMaximumWidth(300)
     self.setIndentation(10)
     self.setAnimated(True)
     self.newFile()
     self.setSortingEnabled(True)
     self.setWindowTitle("Dir View")
     self.hideColumn(1)
     self.resize(200, 600)
     self.hideColumn(2)
     self.confirmation = MessageBox()
     self.hideColumn(3)
     # self.layout.addWidget(self)
     self.doubleClicked.connect(self.openFile)
Exemple #3
0
    def __init__(self):
        super().__init__()
        self.editor = Editor(self)
        self.editor.setReadOnly(True)
        self.custom = Customize()
        self.font = QFont()
        self.numbers = NumberBar(self.editor, index=self.custom.index)

        self.dialog = MessageBox()
        # self.font.setFamily(editor["editorFont"])
        self.font.setFamily("Iosevka")
        self.terminateButton = QPushButton()
        self.terminateButton.setIcon(QIcon("resources/square.png"))
        self.terminateButton.clicked.connect(self.terminate)
        self.font.setPointSize(12)
        self.layout = QHBoxLayout()
        self.layout.addWidget(self.numbers)
        self.layout.addWidget(self.editor, 1)
        self.layout.addWidget(self.terminateButton)

        self.setLayout(self.layout)
        self.output = None
        self.setFocusPolicy(Qt.StrongFocus)
        self.error = None
        self.finished = False
        self.editor.setFont(self.font)

        self.process = QProcess()
        self.state = None
        self.process.readyReadStandardError.connect(
            self.onReadyReadStandardError)
        self.process.readyReadStandardOutput.connect(
            self.onReadyReadStandardOutput)
Exemple #4
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.fileName = None
        self.parent = parent
        self.debugging = False
        self.line = None
        self.column = None

        self.wordlist = []
        self.searchtext = None

        self.font = QFont()
        self.font.setFamily("Inconsolata")
        self.pointSize = 12  # TODO: Make this customizable
        self.tabWidth = 4  # TODO: Make this customizable
        self.font.setPointSize(self.pointSize)
        self.dialog = MessageBox(self)
        self.verticalScrollBar().setStyleSheet("""
            background-color: transparent;
            """)

        self.horizontalScrollBar().setStyleSheet("""
            background-color: transparent;
            """)

        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setCaretForegroundColor(QColor("#FFFFFF"))
        self.setEdgeColumn(121)
        self.setEdgeMode(1)
        self.setEdgeColor(QColor("#8c8c8c"))
        self.setFont(self.font)
        self.setMarginSensitivity(1, True)
        self.markerDefine(QsciScintilla.RightArrow, 8)
        self.setMarkerBackgroundColor(QColor('#FF0000'), 8)
        self.indicator_number = 0
        self.indicator_value = 222
        self.indicator_color = QColor("#FF0000")
        self.draw_under_text = True
        # Initializing some stuff
        self.set_brace_colors(QColor("#98b4f9"), QColor("#edf40e"),
                              QColor("#98b4f9"), QColor("red"))

        self.cursorPositionChanged.connect(self.change_col)
        self.textChanged.connect(self.check_lines)

        self.set_linenumbers(QFontMetrics(self.font))
        self.setFoldMarginColors(QColor("#212121"), QColor("#212121"))
        self.set_indentation_settings(self.tabWidth)
Exemple #5
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.onStart(choiceIndex)
        self.status = QStatusBar(self)
        self.custom = Customize()
        # Initializing the main widget where text is displayed
        self.tab = Tabs(self.openFile, app, palette)
        self.tabsOpen = []
        self.pic_opened = False

        if file is not None:
            self.openFile(file)
            self.fileNameChange()

        self.dialog = MessageBox()

        self.pyConsoleOpened = None
        self.setWindowIcon(QIcon('resources/Python-logo-notext.svg_.png')
                           )  # Setting the window icon

        self.setWindowTitle('PyPad')  # Setting the window title
        self.tab.tabs.currentChanged.connect(self.fileNameChange)
        self.search = DocumentSearch()
        self.os = sys.platform
        self.openpy()
        self.openterm()
        self.openterminal()
        self.new()
        self.newProject()
        self.findDocument()
        self.openProjectF()
        self.open()
        self.save()
        self.saveAs()
        self.customize()
        self.exit()

        self.dir_opened = False
        self._dir = None

        # Without this, the whole layout is broken
        self.setCentralWidget(self.tab)
        self.newFileCount = 0  # Tracking how many new files are opened

        self.files = None  # Tracking the current file that is open
        self.pyFileOpened = False  # Tracking if python file is opened, this is useful to delete highlighting

        self.cFileOpened = False
        self.initUI()  # Main UI
Exemple #6
0
    def __init__(self, app=None, palette=None):
        super().__init__()
        self.app = app
        self.palette = palette
        self.setFixedSize(800, 600)
        with open("default.json", "r") as selectedIndex:
            self.index = selectedIndex.read()
            if self.index == "":
                self.index = 0

            selectedIndex.close()
        self.conf = MessageBox()
        self.opened = False
        self.vbox = QVBoxLayout(self)  # Creating the layout

        self.setWindowIcon(QIcon('resources/Python-logo-notext.svg_.png'))

        self.initUI()
Exemple #7
0
    def __init__(self, parent=None):
        super().__init__()
        self.parent = parent
        self.pressed = False
        self.font = QFont()
        self.dialog = MessageBox(self)
        # self.font.setFamily(editor["editorFont"])
        self.font.setFamily("Iosevka")
        self.font.setPointSize(12)
        self.layout = QVBoxLayout()

        self.setLayout(self.layout)
        self.output = None
        self.setFocusPolicy(Qt.StrongFocus)
        self.error = None
        self.finished = False
        self.clicked = False

        self.process = QProcess()
        self.state = None
        self.process.readyReadStandardError.connect(self.onReadyReadStandardError)
        self.process.readyReadStandardOutput.connect(self.onReadyReadStandardOutput)
        self.add()  # Add items to the layout
Exemple #8
0
    def __init__(self, parent):
        super().__init__(parent)

        self.parent = parent
        self.font = QFont()
        self.size = 12
        self.dialog = MessageBox()
        self.menu_font = QFont()
        self.menu_font.setFamily("Iosevka")
        self.menu_font.setPointSize(10)
        self.font.setFamily(editor["editorFont"])
        self.font.setPointSize(editor["editorFontSize"])
        self.focused = None

        self.replace_tabs = 4
        self.setWordWrapMode(4)
        self.setFont(self.font)
        self.l = 0
        self.highlightingRules = []
        self.indexes = None

        self.setTabStopWidth(editor["TabWidth"])
        self.createStandardContextMenu()
        self.setWordWrapMode(QTextOption.NoWrap)
Exemple #9
0
class Customize(QWidget):
    def __init__(self, app=None, palette=None):
        super().__init__()
        self.app = app
        self.palette = palette
        self.setFixedSize(800, 600)
        with open("default.json", "r") as selectedIndex:
            self.index = selectedIndex.read()
            if self.index == "":
                self.index = 0

            selectedIndex.close()
        self.conf = MessageBox()
        self.opened = False
        self.vbox = QVBoxLayout(self)  # Creating the layout

        self.setWindowIcon(QIcon('resources/Python-logo-notext.svg_.png'))

        self.initUI()

    def initUI(self):

        self.LayoutImage = QLabel(self)
        self.LayoutText = QLabel(self)

        self.hbox = QHBoxLayout()

        editor = config0['editor']

        self.font = QFont()
        self.font.setFamily(editor["editorFont"])
        self.font.setPointSize(editor["editorFontSize"])

        self.combo = QComboBox(self)
        self.combo.addItem("Theme 1")
        self.combo.addItem("Theme 2")
        self.combo.addItem("Theme 3")
        self.combo.currentIndexChanged.connect(self.themes)
        self.combo.setFont(self.font)

        self.theme1 = QPixmap(
            'resources/layout1.png')  # These are the pictures of themes
        self.theme2 = QPixmap('resources/layout1.png')
        self.theme3 = QPixmap('resources/layout1.png')

        self.vbox.addWidget(
            self.combo
        )  # Adding Combobox to vertical boxlayout so it would look better

        self.LayoutText.setFont(self.font)

        self.hbox.addWidget(self.LayoutText)
        self.hbox.addWidget(self.LayoutImage)

        self.LayoutImage.setPixmap(self.theme1)  # This is the "main" theme
        self.LayoutImage.resize(415, 287)

        self.LayoutText.setText("Dark theme")

        self.vbox.addLayout(self.hbox)

        self.selector = QPushButton(self)
        self.selector.setFixedSize(100, 30)
        self.selector.setLayoutDirection(Qt.RightToLeft)
        self.selector.setText("Select")
        self.selector.setFont(self.font)

        self.vbox.addWidget(self.selector)
        self.setLayout(self.vbox)

    def run(self):
        self.show()

    def themes(self, index):

        if index == 0:
            self.LayoutImage.setPixmap(self.theme1)
            self.LayoutText.setText("Dark theme")

        elif index == 1:

            self.LayoutImage.setPixmap(self.theme3)
            self.LayoutText.setText("Fancy theme")

        elif index == 2:

            self.LayoutImage.setPixmap(self.theme2)
            self.LayoutText.setText("Light theme")

        else:
            pass

    def test(self):
        index = self.combo.currentIndex()
        self.index = str(index)
        self.conf.confirmation(index + 1)
        with open("default.json", "w+") as write:
            write.write(str(self.index))
            write.close()
        if index == 0 and self.app is not None and self.palette is not None:
            editor = config0['editor']
            self.palette.setColor(QPalette.Window,
                                  QColor(editor["windowColor"]))
            self.palette.setColor(QPalette.WindowText,
                                  QColor(editor["windowText"]))
            self.palette.setColor(QPalette.Base, QColor(editor["editorColor"]))
            self.palette.setColor(QPalette.AlternateBase,
                                  QColor(editor["alternateBase"]))
            self.palette.setColor(QPalette.ToolTipBase,
                                  QColor(editor["ToolTipBase"]))
            self.palette.setColor(QPalette.ToolTipText,
                                  QColor(editor["ToolTipText"]))
            self.palette.setColor(QPalette.Text, QColor(editor["editorText"]))
            self.palette.setColor(QPalette.Button,
                                  QColor(editor["buttonColor"]))
            self.palette.setColor(QPalette.ButtonText,
                                  QColor(editor["buttonTextColor"]))
            self.palette.setColor(QPalette.Highlight,
                                  QColor(editor["HighlightColor"]).lighter())
            self.palette.setColor(QPalette.HighlightedText,
                                  QColor(editor["HighlightedTextColor"]))

        elif index == 1 and self.app is not None and self.palette is not None:
            editor = config1['editor']
            self.palette.setColor(QPalette.Window,
                                  QColor(editor["windowColor"]))
            self.palette.setColor(QPalette.WindowText,
                                  QColor(editor["windowText"]))
            self.palette.setColor(QPalette.Base, QColor(editor["editorColor"]))
            self.palette.setColor(QPalette.AlternateBase,
                                  QColor(editor["alternateBase"]))
            self.palette.setColor(QPalette.ToolTipBase,
                                  QColor(editor["ToolTipBase"]))
            self.palette.setColor(QPalette.ToolTipText,
                                  QColor(editor["ToolTipText"]))
            self.palette.setColor(QPalette.Text, QColor(editor["editorText"]))
            self.palette.setColor(QPalette.Button,
                                  QColor(editor["buttonColor"]))
            self.palette.setColor(QPalette.ButtonText,
                                  QColor(editor["buttonTextColor"]))
            self.palette.setColor(QPalette.Highlight,
                                  QColor(editor["HighlightColor"]).lighter())
            self.palette.setColor(QPalette.HighlightedText,
                                  QColor(editor["HighlightedTextColor"]))

        elif index == 2 and self.app is not None or self.palette is not None:
            editor = config2['editor']
            self.palette.setColor(QPalette.Window,
                                  QColor(editor["windowColor"]))
            self.palette.setColor(QPalette.WindowText,
                                  QColor(editor["windowText"]))
            self.palette.setColor(QPalette.Base, QColor(editor["editorColor"]))
            self.palette.setColor(QPalette.AlternateBase,
                                  QColor(editor["alternateBase"]))
            self.palette.setColor(QPalette.ToolTipBase,
                                  QColor(editor["ToolTipBase"]))
            self.palette.setColor(QPalette.ToolTipText,
                                  QColor(editor["ToolTipText"]))
            self.palette.setColor(QPalette.Text, QColor(editor["editorText"]))
            self.palette.setColor(QPalette.Button,
                                  QColor(editor["buttonColor"]))
            self.palette.setColor(QPalette.ButtonText,
                                  QColor(editor["buttonTextColor"]))
            self.palette.setColor(QPalette.Highlight,
                                  QColor(editor["HighlightColor"]).lighter())
            self.palette.setColor(QPalette.HighlightedText,
                                  QColor(editor["HighlightedTextColor"]))

        self.app.setPalette(self.palette)
Exemple #10
0
class Main(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.onStart(choiceIndex)
        self.status = QStatusBar(self)
        self.custom = Customize()
        # Initializing the main widget where text is displayed
        self.tab = Tabs(self.openFile, app, palette)
        self.tabsOpen = []
        self.pic_opened = False

        if file is not None:
            self.openFile(file)
            self.fileNameChange()

        self.dialog = MessageBox()

        self.pyConsoleOpened = None
        self.setWindowIcon(QIcon('resources/Python-logo-notext.svg_.png')
                           )  # Setting the window icon

        self.setWindowTitle('PyPad')  # Setting the window title
        self.tab.tabs.currentChanged.connect(self.fileNameChange)
        self.search = DocumentSearch()
        self.os = sys.platform
        self.openPy()
        self.openTerm()
        self.new()
        self.newProject()
        self.findDocument()
        self.openProjectF()
        self.open()
        self.save()
        self.saveAs()
        self.customize()
        self.exit()

        self.dir_opened = False
        self._dir = None

        # Without this, the whole layout is broken
        self.setCentralWidget(self.tab)
        self.newFileCount = 0  # Tracking how many new files are opened

        self.files = None  # Tracking the current file that is open
        self.pyFileOpened = False  # Tracking if python file is opened, this is useful to delete highlighting

        self.cFileOpened = False
        self.initUI()  # Main UI

    def fileNameChange(self):
        try:
            currentFileName = self.tab.tabs.currentWidget().baseName
            self.setWindowTitle("PyPad ~ " + str(currentFileName))

        except AttributeError:
            self.setWindowTitle("PyPad ~ ")

    def onStart(self, index):

        if index == 0:
            editor = config0['editor']

        elif index == 1:
            editor = config1['editor']

        elif index == 2:
            editor = config2['editor']

        else:
            editor = config0['editor']

        if editor["windowStaysOnTop"] is True:
            self.setWindowFlags(Qt.WindowStaysOnTopHint)

        else:
            pass

        self.font = QFont()
        self.font.setFamily(editor["editorFont"])

        self.font.setPointSize(editor["editorFontSize"])
        self.tabSize = editor["TabWidth"]

    def initUI(self):

        self.setStatusBar(self.status)  # Initializing the status bar

        self.font.setFixedPitch(True)
        menuFont = QFont()
        menuFont.setFamily(editor["menuFont"])
        menuFont.setPointSize(editor['menuFontSize'])
        menu = self.menuBar()
        menu.setFont(menuFont)
        # Creating the file menu

        fileMenu = menu.addMenu('File')

        # Adding options to the file menu
        # self.setStatusBar(self.status)
        fileMenu.addAction(self.newAct)
        fileMenu.addAction(self.newProjectAct)
        fileMenu.addAction(self.openAct)
        fileMenu.addAction(self.openProjectAct)
        fileMenu.addAction(self.saveAct)
        fileMenu.addAction(self.saveAsAct)
        fileMenu.addSeparator()
        fileMenu.addAction(self.exitAct)

        toolMenu = menu.addMenu('Tools')
        toolMenu.addAction(self.openPyAct)
        toolMenu.addAction(self.openTermAct)

        appearance = menu.addMenu('Appearance')

        appearance.addAction(self.colorSchemeAct)

        searchDoc = menu.addMenu('Find document')

        searchDoc.addAction(self.findDocumentAct)

        self.showMaximized()

    def open(self):
        self.openAct = QAction('Open...', self)
        self.openAct.setShortcut('Ctrl+O')

        self.openAct.setStatusTip('Open a file')
        self.openAct.triggered.connect(self.openFileFromMenu)

    def new(self):
        self.newAct = QAction('New')
        self.newAct.setShortcut('Ctrl+N')

        self.newAct.setStatusTip('Create a new file')
        self.newAct.triggered.connect(self.newFile)

    def newProject(self):
        self.newProjectAct = QAction('New project')
        self.newProjectAct.setShortcut('Ctrl+Shift+N')

        self.newProjectAct.setStatusTip('Create a new project')
        self.newProjectAct.triggered.connect(self.newProjectFolder)

    def openProjectF(self):
        self.openProjectAct = QAction('Open project')
        self.openProjectAct.setShortcut('Ctrl+Shift+O')

        self.openProjectAct.setStatusTip('Open a project')
        self.openProjectAct.triggered.connect(self.openProject)

    def customize(self):
        self.colorSchemeAct = QAction('Customize', self)
        self.colorSchemeAct.setShortcut('Alt+C')

        self.colorSchemeAct.setStatusTip('Select a color scheme')
        self.colorSchemeAct.triggered.connect(self.theme)

    def theme(self):
        self.custom.run()
        self.custom.selector.clicked.connect(self.custom.test)

    def save(self):
        self.saveAct = QAction('Save')
        self.saveAct.setShortcut('Ctrl+S')

        self.saveAct.setStatusTip('Save a file')
        self.saveAct.triggered.connect(self.saveFile)

    def openPy(self):
        self.openPyAct = QAction('IPython console', self)
        self.openPyAct.setShortcut('Ctrl+Y')

        self.openPyAct.setStatusTip('Open IPython console')
        self.openPyAct.triggered.connect(self.Console)

    def openTerm(self):
        self.openTermAct = QAction('Run', self)
        self.openTermAct.setShortcut('Shift+F10')

        self.openTermAct.setStatusTip('Run your code')
        self.openTermAct.triggered.connect(self.Terminal)

    def saveAs(self):
        self.saveAsAct = QAction('Save As...')
        self.saveAsAct.setShortcut('Ctrl+Shift+S')

        self.saveAsAct.setStatusTip('Save a file as')
        self.saveAsAct.triggered.connect(self.saveFileAs)

    def findDocument(self):
        self.findDocumentAct = QAction('Find document')
        self.findDocumentAct.setShortcut('Ctrl+Shift+F')

        self.findDocumentAct.setStatusTip('Find a document')
        self.findDocumentAct.triggered.connect(self.findDocumentFunc)

    def findDocumentFunc(self):

        self.search.run()

    def exit(self):
        self.exitAct = QAction('Quit', self)
        self.exitAct.setShortcut('Ctrl+Q')

        self.exitAct.setStatusTip('Exit application')
        self.exitAct.triggered.connect(qApp.quit)

    def openFileFromMenu(self):
        options = QFileDialog.Options()

        filenames, _ = QFileDialog.getOpenFileNames(
            self,
            'Open a file',
            '',
            'All Files (*);;Python Files (*.py);;Text Files (*.txt)',
            options=options)

        if filenames:  # If file is selected, we can open it
            filename = filenames[0]
            if filename[-3:] in ['gif', 'png', 'jpg', 'bmp'
                                 ] or filename[-4:] in ['jpeg']:
                self.pic_opened = True
            self.openFile(filename)

    def openFile(self, filename):

        try:
            for index, tabName in enumerate(self.tab.tabCounter):
                with open(filename, 'r+') as file_o:
                    if filename[-3:] in ['gif', 'png', 'jpg', 'bmp'
                                         ] or filename[-4:] in ['jpeg']:
                        self.pic_opened = True
                    else:
                        self.pic_opened = False
                    try:
                        text = file_o.read()

                    except UnicodeDecodeError as E:
                        text = str(E)

                    basename = os.path.basename(filename)
                    if not self.pic_opened:
                        tab = Content(text, filename, basename,
                                      self.custom.index, self, ex)
                        tab.saved = True
                        tab.modified = False
                    else:
                        tab = Image(filename, basename)
                if tabName == tab.baseName:
                    self.tab.tabs.removeTab(index)

                    self.tab.tabCounter.remove(tab.baseName)
            try:
                with open(filename, 'r+') as file_o:
                    try:
                        if self.pic_opened is not True:
                            text = file_o.read()
                        else:
                            text = None
                    except (FileNotFoundError, UnicodeDecodeError,
                            AttributeError) as E:
                        text = str(E)

            except FileNotFoundError:
                with open(filename, 'w+') as newFileCreated:
                    text = newFileCreated.read()
            basename = os.path.basename(filename)
            if self.pic_opened is True:
                tab = Image(filename, basename)

            else:
                tab = Content(text, filename, basename, self.custom.index,
                              self, ex)  # Creating a tab object *IMPORTANT*
                tab.saved = True
                tab.modified = False
            self.tab.tabCounter.append(tab.baseName)
            dirPath = os.path.dirname(filename)
            self.files = filename

            self.tabsOpen.append(self.files)

            index = self.tab.tabs.addTab(
                tab, tab.fileName
            )  # This is the index which we will use to set the current
            if not self.dir_opened:  # If a project isnt opened then we open a directory everytime we open a file
                self.tab.directory.openDirectory(dirPath)

                self.tab.showDirectory()
            else:
                pass

            self.tab.setLayout(self.tab.layout)  # Finally we set the layout

            self.tab.tabs.setCurrentIndex(
                index)  # Setting the index so we could find the current widget

            self.currentTab = self.tab.tabs.currentWidget()

            if self.pic_opened is not True:
                self.currentTab.editor.setFont(self.font)  # Setting the font
                self.currentTab.editor.setTabStopWidth(
                    self.tabSize)  # Setting tab size
                self.currentTab.editor.setFocus(
                )  # Setting focus to the tab after we open it

            self.pic_opened = False
        except (IsADirectoryError, AttributeError, UnboundLocalError,
                PermissionError) as E:
            print(E)

    def newFile(self):
        text = ""

        if self._dir:
            fileName = str(self._dir) + "/" + "Untitled_file_" + str(
                random.randint(1, 100)) + ".py"
        else:
            current = os.getcwd()
            fileName = current + "/" + "Untitled_file_" + str(
                random.randint(1, 100)) + ".py"

        self.pyFileOpened = True
        # Creates a new blank file
        file = Content(text, fileName, fileName, self.custom.index, self, ex)

        self.tab.splitterH.addWidget(
            self.tab.tabs
        )  # Adding tabs, now the directory tree will be on the left
        self.tab.tabCounter.append(file.fileName)
        self.tab.setLayout(self.tab.layout)  # Finally we set the layout
        index = self.tab.tabs.addTab(
            file, file.fileName
        )  # addTab method returns an index for the tab that was added
        self.tab.tabs.setCurrentIndex(
            index)  # Setting focus to the new tab that we created
        widget = self.tab.tabs.currentWidget()

        widget.editor.setFocus()
        widget.editor.setFont(self.font)
        widget.editor.setTabStopWidth(self.tabSize)

    def newProjectFolder(self):
        self.dialog = MessageBox()
        self.dialog.newProject()

    def openProject(self):

        self._dir = QFileDialog.getExistingDirectory(None, 'Select a folder:',
                                                     '',
                                                     QFileDialog.ShowDirsOnly)

        self.tab.directory.openDirectory(self._dir)
        self.dir_opened = True
        self.tab.showDirectory()

    def saveFile(self):
        try:
            active_tab = self.tab.tabs.currentWidget()
            if self.tab.tabs.count():  # If a file is already opened
                with open(active_tab.fileName, 'w+') as saveFile:
                    saveFile.write(active_tab.editor.toPlainText())
                    active_tab.saved = True

                    active_tab.modified = False
                    saveFile.close()
                active_tab.tokenize_file()
            else:
                options = QFileDialog.Options()
                name = QFileDialog.getSaveFileName(
                    self,
                    'Save File',
                    '',
                    'All Files (*);;Python Files (*.py);;Text Files (*.txt)',
                    options=options)
                fileName = name[0]
                with open(fileName, "w+") as saveFile:
                    active_tab.saved = True
                    active_tab.modified = False
                    self.tabsOpen.append(fileName)
                    saveFile.write(active_tab.editor.toPlainText())
                    saveFile.close()
            ex.setWindowTitle("PyPad ~ " + str(active_tab.baseName) +
                              " [SAVED]")
            active_tab.tokenize_file()
        except Exception as E:
            print(E)

    def saveFileAs(self):
        try:
            active_tab = self.tab.tabs.currentWidget()
            if active_tab is not None:
                active_index = self.tab.tabs.currentIndex()

                options = QFileDialog.Options()
                name = QFileDialog.getSaveFileName(
                    self,
                    'Save File',
                    '',
                    'All Files (*);;Python Files (*.py);;Text Files (*.txt)',
                    options=options)
                fileName = name[0]
                with open(fileName, "w+") as saveFile:
                    active_tab.saved = True
                    active_tab.modified = False
                    self.tabsOpen.append(fileName)

                    try:
                        baseName = os.path.basename(fileName)
                    except AttributeError:
                        print("All tabs closed")
                    saveFile.write(active_tab.editor.toPlainText())
                    text = active_tab.editor.toPlainText()
                    newTab = Content(str(text), fileName, baseName,
                                     self.custom.index, self, ex)

                    self.tab.tabs.removeTab(
                        active_index
                    )  # When user changes the tab name we make sure we delete the old one
                    index = self.tab.tabs.addTab(
                        newTab, newTab.fileName)  # And add the new one!

                    self.tab.tabs.setCurrentIndex(index)
                    newActiveTab = self.tab.tabs.currentWidget()

                    newActiveTab.editor.setFont(self.font)
                    newActiveTab.editor.setFocus()

                    if fileName.endswith(
                            ".py"
                    ):  # If we are dealing with a python file we use highlighting on it
                        self.pyhighlighter = PyHighlighter(
                            newActiveTab.editor.document(),
                            index=self.custom.index)

                        newActiveTab.editor.setTabStopWidth(self.tabSize)

                    saveFile.close()
                ex.setWindowTitle("PyPad ~ " + str(active_tab.baseName) +
                                  " [SAVED]")

            else:
                print("No file opened")

        except FileNotFoundError:
            print("File dialog closed")

    def Console(self):

        self.pyConsoleOpened = True
        self.ind = self.tab.splitterV.indexOf(self.tab.term)

        self.o = self.tab.splitterV.indexOf(self.tab.Console)

        if self.tab.splitterV.indexOf(
                self.tab.Console
        ) == -1:  # If the Console widget DOESNT EXIST YET!

            self.tab.splitterV.addWidget(self.tab.term)

            self.ind = self.tab.splitterV.indexOf(self.tab.term)

        if self.tab.splitterV.indexOf(
                self.tab.term
        ) == -1:  # If the terminal widget doesnt exist yet
            self.tab.splitterV.replaceWidget(self.o, self.tab.term)
            self.o = self.tab.splitterV.indexOf(self.tab.Console)

            self.ind = self.tab.splitterV.indexOf(self.tab.term)

    def Terminal(self):

        active_tab = self.tab.tabs.currentWidget()
        if self.pyConsoleOpened:
            self.o = self.tab.splitterV.indexOf(self.tab.Console)

            self.ind = self.tab.splitterV.indexOf(self.tab.term)

            if self.ind == -1:
                if platform.system() == "Linux":
                    self.tab.Console.run("python3 " + active_tab.fileName)

                elif platform.system() == "Windows":
                    self.tab.Console.run("python " + active_tab.fileName)

                else:
                    self.tab.Console.run("python3 " + active_tab.fileName)

            else:
                self.tab.splitterV.replaceWidget(self.ind, self.tab.Console)

            try:

                if platform.system() == "Linux":
                    self.tab.Console.run("python3 " + active_tab.fileName)

                elif platform.system() == "Windows":
                    self.tab.Console.run("python " + active_tab.fileName)

                else:
                    self.tab.Console.run("python3 " + active_tab.fileName)

            except AttributeError as E:
                print(E)
        else:
            self.tab.splitterV.addWidget(self.tab.Console)

            try:
                active_tab = self.tab.tabs.currentWidget()

                if platform.system() == "Linux":
                    self.tab.Console.run("python3 " + active_tab.fileName)

                elif platform.system() == "Windows":
                    self.tab.Console.run("python " + active_tab.fileName)

                else:
                    self.tab.Console.run("python3 " + active_tab.fileName)

            except AttributeError as E:
                print(E)
Exemple #11
0
class Tabs(QWidget):
    def __init__(self, callback, app, palette):
        super().__init__()
        self.app = app
        self.palette = palette
        self.layout = QHBoxLayout(self)
        # Initialize tab screen
        self.tabs = QTabWidget()
        font = QFont(editor['tabFont'])
        font.setPointSize(
            editor["tabFontSize"])  # This is the tab font and font size
        self.tabs.setFont(font)

        self.dialog = MessageBox()
        self.tabs.usesScrollButtons()
        self.filelist = []

        self.tabSaved = False

        self.Console = Terminal(
        )  # This is the terminal widget and the SECOND thread
        self.term = IPythonWidget()
        self.directory = Directory(callback, self.app,
                                   self.palette)  # TODO: This is top left
        self.directory.clearSelection()
        self.tabCounter = []
        # Add tabs
        self.tab_layout = QHBoxLayout(
        )  # Create new layout for original tab layout
        self.tab_layout.addWidget(self.tabs)  # Add tab widget to tab layout
        self.search_layout = QHBoxLayout()

        self.tabs.setTabsClosable(True)
        self.tabs.setMovable(
            editor['tabMovable'])  # Let's you make the tabs movable

        if editor[
                'tabShape'] is True:  # If tab shape is true then they have this rounded look
            self.tabs.setTabShape(1)

        else:
            self.tabs.setTabShape(0)  # If false, it has this boxy look

        self.tabs.tabCloseRequested.connect(self.closeTab)

        # Add Console
        self.console_layout = QHBoxLayout()  # Create console layout
        self.console_layout.addWidget(
            self.term)  # Add console to console layout

        # Build Layout
        self.layout.addLayout(
            self.tab_layout)  # Adds 'TOP' layout : tab + directory
        self.layout.addLayout(self.search_layout)

        # Creating horizontal splitter
        self.splitterH = QSplitter(Qt.Horizontal)

        # Creating vertical splitter
        self.splitterV = QSplitter(Qt.Vertical)
        self.splitterV.addWidget(self.splitterH)
        self.layout.addWidget(self.splitterV)
        self.splitterV.setSizes([300, 10])
        self.setLayout(self.layout)  # Sets layout of QWidget

        self.closeShortcut = QShortcut(
            QKeySequence(editor["closeTabShortcut"]), self)
        self.closeShortcut.activated.connect(self.closeTabShortcut)

        self.getAllOpenTabs = QShortcut(QKeySequence("Ctrl+Shift+W"), self)
        self.getAllOpenTabs.activated.connect(self.getAllOpenTabsFunc)

        currentTab = self.tabs.currentWidget()
        self.hideDirectory()
        """
    def hideDirectory(self):
        self.tab_layout.removeWidget(self.directory)
        self.directory.setVisible(False)"""

    @pyqtSlot()
    def closeTabShortcut(self):
        self.index = self.tabs.currentIndex()
        self.closeTab(self.index)

    def getAllOpenTabsFunc(self):
        word = 'import'
        for tab in range(self.tabs.count()):
            file = self.tabs.widget(tab).fileName
            if file not in self.filelist:
                self.filelist.append(file)

        for file in self.filelist:
            openedFileContents = open(file, 'r').read()

    def closeTab(self, index):
        try:

            tab = self.tabs.widget(index)

            if tab.saved is True and tab.modified is False:
                tab.deleteLater()
                self.tabCounter.pop(index)
                self.filelist.pop(index)
                self.tabs.removeTab(index)

            elif tab.modified is True:
                self.dialog.saveMaybe(tab, self.tabCounter, self.tabs, index)

        except (AttributeError, IndexError) as E:
            try:
                tab.deleteLater()
                self.tabCounter.pop(index)
                self.filelist.pop(index)
                self.tabs.removeTab(index)
            except (AttributeError, IndexError) as E:
                print(E)

    def showDirectory(self):
        self.directory.setVisible(True)
        self.tab_layout.removeWidget(self.tabs)
        self.splitterH.addWidget(
            self.directory
        )  # Adding that directory widget in the Tab class BEFORE the tabs
        self.splitterH.addWidget(
            self.tabs
        )  # Adding tabs, now the directory tree will be on the left

    def hideDirectory(self):
        self.tab_layout.removeWidget(self.directory)
        self.directory.setVisible(False)

    """
    Because the root layouts are set all you have to do now is just add/remove widgets from the parent layout associated.
    This keeps the UI order set as intended as built above when initialized.
    """

    def showConsole(self):
        pass

    def currentTab(self):
        return self.tabs.currentWidget()
Exemple #12
0
class Console(QWidget):
    errorSignal = pyqtSignal(str)
    outputSignal = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.editor = Editor(self)
        self.editor.setReadOnly(True)
        self.custom = Customize()
        self.font = QFont()
        self.numbers = NumberBar(self.editor, index=self.custom.index)

        self.dialog = MessageBox()
        # self.font.setFamily(editor["editorFont"])
        self.font.setFamily("Iosevka")
        self.terminateButton = QPushButton()
        self.terminateButton.setIcon(QIcon("resources/square.png"))
        self.terminateButton.clicked.connect(self.terminate)
        self.font.setPointSize(12)
        self.layout = QHBoxLayout()
        self.layout.addWidget(self.numbers)
        self.layout.addWidget(self.editor, 1)
        self.layout.addWidget(self.terminateButton)

        self.setLayout(self.layout)
        self.output = None
        self.setFocusPolicy(Qt.StrongFocus)
        self.error = None
        self.finished = False
        self.editor.setFont(self.font)

        self.process = QProcess()
        self.state = None
        self.process.readyReadStandardError.connect(
            self.onReadyReadStandardError)
        self.process.readyReadStandardOutput.connect(
            self.onReadyReadStandardOutput)

    def onReadyReadStandardError(self):
        try:
            self.error = self.process.readAllStandardError().data().decode()

            self.editor.appendPlainText(self.error)

            self.errorSignal.emit(self.error)
            if self.error == "":
                pass
            else:
                self.error = self.error.split(os.linesep)[-2]
                self.dialog.helpword = str(self.error)
                self.dialog.getHelp()
        except IndexError as E:
            print(E)

    def onReadyReadStandardOutput(self):
        try:
            self.result = self.process.readAllStandardOutput().data().decode()
        except UnicodeDecodeError as E:
            print(E)
        self.editor.appendPlainText(self.result.strip("\n"))
        self.state = self.process.state()

        self.outputSignal.emit(self.result)

    def ifFinished(self, exitCode, exitStatus):
        self.finished = True

    def run(self, command):
        """Executes a system command."""
        # clear previous text
        self.editor.clear()
        # self.editor.setPlainText("[" + str(getpass.getuser()) + "@" + str( socket.gethostname()) + "]" +
        #"   ~/" + str(os.path.basename(os.getcwd())) + " >$")

        if self.process.state() == 1 or self.process.state() == 2:
            self.process.kill()
            self.editor.setPlainText("Process already started, terminating")
        else:
            self.process.start(command)

    def terminate(self):

        if self.process.state() == 2:
            self.process.kill()
Exemple #13
0
    def __init__(self, callback, app, palette):
        super().__init__()
        self.app = app
        self.palette = palette
        self.layout = QHBoxLayout(self)
        # Initialize tab screen
        self.tabs = QTabWidget()
        font = QFont(editor['tabFont'])
        font.setPointSize(
            editor["tabFontSize"])  # This is the tab font and font size
        self.tabs.setFont(font)

        self.dialog = MessageBox()
        self.tabs.usesScrollButtons()
        self.filelist = []

        self.tabSaved = False

        self.Console = Terminal(
        )  # This is the terminal widget and the SECOND thread
        self.term = IPythonWidget()
        self.directory = Directory(callback, self.app,
                                   self.palette)  # TODO: This is top left
        self.directory.clearSelection()
        self.tabCounter = []
        # Add tabs
        self.tab_layout = QHBoxLayout(
        )  # Create new layout for original tab layout
        self.tab_layout.addWidget(self.tabs)  # Add tab widget to tab layout
        self.search_layout = QHBoxLayout()

        self.tabs.setTabsClosable(True)
        self.tabs.setMovable(
            editor['tabMovable'])  # Let's you make the tabs movable

        if editor[
                'tabShape'] is True:  # If tab shape is true then they have this rounded look
            self.tabs.setTabShape(1)

        else:
            self.tabs.setTabShape(0)  # If false, it has this boxy look

        self.tabs.tabCloseRequested.connect(self.closeTab)

        # Add Console
        self.console_layout = QHBoxLayout()  # Create console layout
        self.console_layout.addWidget(
            self.term)  # Add console to console layout

        # Build Layout
        self.layout.addLayout(
            self.tab_layout)  # Adds 'TOP' layout : tab + directory
        self.layout.addLayout(self.search_layout)

        # Creating horizontal splitter
        self.splitterH = QSplitter(Qt.Horizontal)

        # Creating vertical splitter
        self.splitterV = QSplitter(Qt.Vertical)
        self.splitterV.addWidget(self.splitterH)
        self.layout.addWidget(self.splitterV)
        self.splitterV.setSizes([300, 10])
        self.setLayout(self.layout)  # Sets layout of QWidget

        self.closeShortcut = QShortcut(
            QKeySequence(editor["closeTabShortcut"]), self)
        self.closeShortcut.activated.connect(self.closeTabShortcut)

        self.getAllOpenTabs = QShortcut(QKeySequence("Ctrl+Shift+W"), self)
        self.getAllOpenTabs.activated.connect(self.getAllOpenTabsFunc)

        currentTab = self.tabs.currentWidget()
        self.hideDirectory()
        """
Exemple #14
0
class Directory(QTreeView):
    def __init__(self, callback, app=None, palette=None):
        super().__init__()
        directoryFont = QFont()
        self.app = app
        self.palette = palette
        directoryFont.setFamily(editor["directoryFont"])
        directoryFont.setPointSize(editor["directoryFontSize"])
        self.open_callback = callback
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.openMenu)
        self.setFont(directoryFont)
        self.layout = QHBoxLayout()
        self.model = QFileSystemModel()
        self.setModel(self.model)
        self.model.setRootPath(QDir.rootPath())
        self.setMaximumWidth(300)
        self.setIndentation(10)
        self.setAnimated(True)
        self.newFile()
        self.setSortingEnabled(True)
        self.setWindowTitle("Dir View")
        self.hideColumn(1)
        self.resize(200, 600)
        self.hideColumn(2)
        self.confirmation = MessageBox()
        self.hideColumn(3)
        # self.layout.addWidget(self)
        self.doubleClicked.connect(self.openFile)

    def newFile(self):
        self.newAct = QAction('New')
        self.newAct.setStatusTip('Create a new file')
        self.newAct.triggered.connect(lambda: print("new file created lol"))

    def openMenu(self, position):

        indexes = self.selectedIndexes()
        if len(indexes) > 0:
            level = 0
            index = indexes[0]
            while index.parent().isValid():
                index = index.parent()
                level += 1

        menu = QMenu()
        menu.addAction(
            self.newAct
        )  # TODO: Add more context menu stuff and make them functional
        menu.exec_(self.viewport().mapToGlobal(position))

    def focusInEvent(self, event):
        # If we are focused then we change the selected item highlighting color
        self.focused = True
        self.palette.setColor(QPalette.Highlight,
                              QColor(editor["HighlightColor"]).lighter())

        self.app.setPalette(self.palette)

    def focusOutEvent(self, event):
        # If we un focus from the QTreeView then we make the highlighted item color white
        self.palette.setColor(
            QPalette.Highlight,
            QColor(editor["UnfocusedHighlightColor"]).lighter())
        # self.clearSelection() Uncomment this if you want to remove all highlighting when unfocused
        self.app.setPalette(self.palette)

    def openDirectory(self, path):
        self.setRootIndex(self.model.index(path))

    def openFile(self, signal):
        file_path = self.model.filePath(signal)
        self.open_callback(file_path)
        return file_path

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

            try:
                self.fileObject = self.selectedIndexes()[0]
                fileName = self.model.filePath(self.fileObject)
                self.confirmation.run("Are you sure you want to delete ",
                                      str(fileName))

            except IndexError:
                print("No file selected")
Exemple #15
0
class Editor(QPlainTextEdit):
    def __init__(self, parent):
        super().__init__(parent)
        self.lineNumberArea = QLineNumberArea(self)
        self.blockCountChanged.connect(self.updateLineNumberAreaWidth)
        self.updateRequest.connect(self.updateLineNumberArea)
        self.cursorPositionChanged.connect(self.highlightCurrentLine)
        self.updateLineNumberAreaWidth(0)
        self.parent = parent
        self.font = QFont()
        self.size = 12
        self.dialog = MessageBox(self)
        self.menu_font = QFont()
        self.menu_font.setFamily("Iosevka")
        self.menu_font.setPointSize(10)
        self.font.setFamily(editor["editorFont"])
        self.font.setPointSize(editor["editorFontSize"])
        self.focused = None
        self.text = None
        self.replace_tabs = 4
        self.setWordWrapMode(4)
        self.setFont(self.font)
        self.l = 0
        self.highlightingRules = []
        self.indexes = None

        self.setTabStopWidth(editor["TabWidth"])
        self.createStandardContextMenu()
        self.setWordWrapMode(QTextOption.NoWrap)

    def getTextCursor(self):
        textCursor = self.textCursor()
        textCursorPos = textCursor.position()

        return textCursor, textCursorPos

    def get_linenumbers(self):
        return self.blockCount()

    def check(self):
        cursor = self.textCursor()
        b = cursor.block()
        extraSelections = []
        if len(b.text()) > 120:
            selection = QTextEdit.ExtraSelection()
            # TODO: implement something using flake8
            selection.format.setFontUnderline(True)
            selection.format.setUnderlineColor(QColor("#FF0000"))

            selection.format.setUnderlineStyle(
                QTextCharFormat.SpellCheckUnderline)
            selection.format.setProperty(QTextFormat.FullWidthSelection, True)

            selection.cursor = self.textCursor()
            selection.cursor.clearSelection()

            extraSelections.append(selection)
            self.setExtraSelections(extraSelections)

            font = QFont()
            font.setFamily("Iosevka")
            font.setPointSize(10)

            QToolTip.setFont(font)
            cursor = self.textCursor()
            current_line = cursor.positionInBlock()
            QToolTip.showText(
                QCursor.pos(), "Line too long (" + str(current_line) +
                "> 120) | violation on line: " + str(b.blockNumber() + 1))

    def newFile(self):
        """This is a wrapper for the function defined in Main"""

        self.new_action = QAction("New")
        self.new_action.triggered.connect(self.parent.parent.newFile)

    def lineNumberAreaWidth(self):
        digits = 1
        max_value = max(1, self.blockCount())
        while max_value >= 10:
            max_value /= 10
            digits += 1
        space = 10 + self.fontMetrics().width('9') * digits
        return space

    def updateLineNumberAreaWidth(self, _):
        self.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0)

    def updateLineNumberArea(self, rect, dy):
        if dy:
            self.lineNumberArea.scroll(0, dy)
        else:
            self.lineNumberArea.update(0, rect.y(),
                                       self.lineNumberArea.width(),
                                       rect.height())
        if rect.contains(self.viewport().rect()):
            self.updateLineNumberAreaWidth(0)

    def resizeEvent(self, event):
        super().resizeEvent(event)
        cr = self.contentsRect()
        self.lineNumberArea.setGeometry(
            QRect(cr.left(), cr.top(), self.lineNumberAreaWidth(),
                  cr.height()))

    def highlightCurrentLine(self):
        extraSelections = []
        if not self.isReadOnly():
            selection = QTextEdit.ExtraSelection()
            lineColor = QColor("#434343")
            selection.format.setBackground(lineColor)
            selection.format.setProperty(QTextFormat.FullWidthSelection, True)
            selection.cursor = self.textCursor()
            selection.cursor.clearSelection()
            extraSelections.append(selection)
        self.setExtraSelections(extraSelections)
        self.check()

    def lineNumberAreaPaintEvent(self, event):
        painter = QPainter(self.lineNumberArea)

        painter.fillRect(event.rect(), QColor("#303030"))

        block = self.firstVisibleBlock()
        blockNumber = block.blockNumber()
        top = self.blockBoundingGeometry(block).translated(
            self.contentOffset()).top()
        bottom = top + self.blockBoundingRect(block).height()

        # Just to make sure I use the right font
        height = self.fontMetrics().height()

        while block.isValid() and (top <= event.rect().bottom()):
            if block.isVisible() and (bottom >= event.rect().top()):
                number = str(blockNumber + 1)
                painter.setPen(Qt.white)
                painter.drawText(0, top, self.lineNumberArea.width(), height,
                                 Qt.AlignCenter, number)

            block = block.next()
            top = bottom
            bottom = top + self.blockBoundingRect(block).height()
            blockNumber += 1

    def openFile(self):

        self.open_action = QAction("Open")
        self.open_action.triggered.connect(self.parent.parent.openFileFromMenu)

    def runFile(self):

        self.run_action = QAction("Run")
        self.run_action.triggered.connect(self.parent.parent.terminal)

    def textUnderCursor(self):
        textCursor = self.textCursor()
        textCursor.select(QTextCursor.WordUnderCursor)

        return textCursor.selectedText()

    def contextMenuEvent(self, event):

        menu = QMenu()
        """Initializing actions"""
        self.newFile()
        self.openFile()
        self.runFile()
        menu.addAction(self.new_action)
        menu.addAction(self.open_action)
        menu.addAction(self.run_action)

        menu.setFont(self.menu_font)

        menu.exec(event.globalPos())
        del menu

    def moveCursorPosBack(self):
        textCursor = self.textCursor()
        textCursorPos = textCursor.position()

        textCursor.setPosition(textCursorPos - 1)
        self.setTextCursor(textCursor)

    def mousePressEvent(self, e):

        self.check()
        if QApplication.queryKeyboardModifiers() == Qt.ControlModifier:
            if self.text is not None:
                self.check_func("lol")
                url = "https://docs.python.org/3/library/functions.html#" + self.text
                word = self.text
                self.parent.parent.showBrowser(url, word)
        QApplication.restoreOverrideCursor()
        super().mousePressEvent(e)

    def check_func(self, word):
        funcs = [
            "abs", "all", "any", "ascii", "bin", "bool", "breakpoint",
            "bytearray", "bytes", "callable", "chr", "classmethod", "compile",
            "complex", "delattr", "dict", "dir", "divmod", "enumerate", "eval",
            "exec", "filter", "float", "format", "frozenset", "getattr",
            "globals", "hasattr", "hash", "help", "hex", "id", "input", "int",
            "isinstance", "issubclass", "iter", "len", "list", "locals", "map",
            "max", "memoryview", "min", "next", "object", "oct", "open", "ord",
            "pow", "print", "property", "range", "repr", "reversed", "round",
            "set", "setattr", "slice", "sorted", "staticmethod", "str", "sum",
            "super", "tuple", "type", "vars", "zip", "__import__"
        ]
        word_array = list(word)
        for wo in word_array:
            if wo in ["{", "}", "'", '"', "[", "]", "(", ")"]:
                word_array.remove(wo)
        for w in funcs:
            if w == "".join(word_array):
                print("".join(word_array))
                return True

    def mouseReleaseEvent(self, e):

        self.check()
        super().mouseReleaseEvent(e)

    def keyPressEvent(self, e):
        textCursor = self.textCursor()
        key = e.key()
        if key == Qt.Key_H:
            # self.parent.completer.wordList
            # TODO: implement dynamic completion
            pass

        if e.modifiers(
        ) == Qt.ControlModifier and key == 16777217:  # that key code stands for tab
            self.parent.parent.switchTabs()

        isSearch = (e.modifiers() == Qt.ControlModifier
                    and e.key() == Qt.Key_F)

        if isSearch:
            try:
                currentWidget = self.parent
                currentFile = currentWidget.fileName
                currentEditor = currentWidget.editor

                textCursor = currentEditor.textCursor()
                textCursorPos = textCursor.position()

            except (AttributeError, UnboundLocalError) as E:
                print(E, " on line 228 in the file Editor.py")

            if currentWidget is not None:
                text, okPressed = QInputDialog.getText(self, 'Find',
                                                       'Find what: ')
                if okPressed:
                    if text == "":
                        text = " "
                        self.dialog.noMatch(text)
                    self.searchtext = text
                    try:
                        with open(currentFile, 'r') as file:
                            contents = file.read()
                            self.indexes = list(find_all(contents, text))
                            if len(self.indexes) == 0:
                                self.dialog.noMatch(text)

                    except FileNotFoundError as E:
                        print(E, " on line 245 in the file Editor.py")

        if key == Qt.Key_QuoteDbl:
            self.insertPlainText('"')
            self.moveCursorPosBack()

        if key == 16777249:  # This code stands for CTRL
            if self.check_func(self.textUnderCursor()):
                extraSelections = []
                selection = QTextEdit.ExtraSelection()
                selection.format.setFontUnderline(True)
                selection.format.setUnderlineColor(QColor("#00d2ff"))
                selection.format.setBackground(QColor("#00d2ff"))
                selection.format.setProperty(QTextFormat.FullWidthSelection,
                                             True)

                selection.cursor = self.textCursor()
                selection.cursor.clearSelection()
                selection.cursor.select(QTextCursor.WordUnderCursor)
                extraSelections.append(selection)
                self.setExtraSelections(extraSelections)
                self.text = self.textUnderCursor()
                QApplication.setOverrideCursor(Qt.PointingHandCursor)
            else:
                self.text = None

        if e.modifiers() == Qt.ControlModifier and e.key(
        ) == 61:  # Press Ctrl+Equal key to make font bigger

            self.font.setPointSize(self.size + 1)
            self.font.setFamily(editor["editorFont"])
            self.setFont(self.font)
            self.size += 1

        if e.modifiers() == Qt.ControlModifier and e.key() == 16777217:
            return

        if e.modifiers() == Qt.ControlModifier and e.key(
        ) == 45:  # Press Ctrl+Minus key to make font smaller

            self.font.setPointSize(self.size - 1)

            self.font.setFamily(editor["editorFont"])
            self.setFont(self.font)
            self.size -= 1

        if key == Qt.Key_F3:
            try:
                index = self.indexes[0 + self.l]
                currentWidget = self.parent
                currentFile = currentWidget.fileName
                currentEditor = currentWidget.editor
                textCursor.setPosition(index)
                textCursor.movePosition(textCursor.Right,
                                        textCursor.KeepAnchor,
                                        len(self.searchtext))
                currentEditor.setTextCursor(textCursor)
                self.l += 1
            except IndexError:
                self.l = 0

        if key == 39:
            self.insertPlainText("'")
            self.moveCursorPosBack()

        if key == Qt.Key_BraceLeft:
            self.insertPlainText("}")
            self.moveCursorPosBack()

        if key == Qt.Key_BracketLeft:
            self.insertPlainText("]")
            self.moveCursorPosBack()

        if key == Qt.Key_ParenLeft:
            self.insertPlainText(")")
            self.moveCursorPosBack()

        if key == Qt.Key_ParenRight:
            textCursor = self.textCursor()
            textCursor.select(QTextCursor.WordUnderCursor)
            if textCursor.selectedText(
            ) == "()" or "()" in textCursor.selectedText():
                return

        if key == Qt.Key_BraceRight:
            textCursor = self.textCursor()
            textCursor.select(QTextCursor.WordUnderCursor)
            if textCursor.selectedText == "":
                return
        if key == 16777219:
            if self.textUnderCursor() in ['""', '()', '[]', "''", "{}"]:
                textCursor = self.textCursor()
                textCursorPos = textCursor.position()

                textCursor.setPosition(textCursorPos + 1)
                textCursor.deletePreviousChar()
                self.setTextCursor(textCursor)
        if key not in [16777217, 16777219, 16777220]:
            super().keyPressEvent(e)
            return

        e.accept()
        cursor = self.textCursor()
        if key == 16777217:  # and self.replace_tabs:
            amount = 4 - self.textCursor().positionInBlock() % 4
            self.insertPlainText(' ' * amount)

        elif key == 16777219 and cursor.selectionStart() == cursor.selectionEnd() and self.replace_tabs and \
                cursor.positionInBlock():
            position = cursor.positionInBlock()
            end = cursor.position()
            start = end - (position % 4)

            if start == end and position >= 4:
                start -= 4

            string = self.toPlainText()[start:end]
            if not len(string.strip()
                       ):  # if length is 0 which is binary for false
                for i in range(end - start):
                    cursor.deletePreviousChar()
            else:
                super().keyPressEvent(e)

        elif key == 16777220:
            end = cursor.position()
            start = end - cursor.positionInBlock()
            line = self.toPlainText()[start:end]
            indentation = len(line) - len(line.lstrip())

            chars = '\t'
            if self.replace_tabs:
                chars = '    '
                indentation /= self.replace_tabs

            if line.endswith(':'):
                if self.replace_tabs:
                    indentation += 1

            super().keyPressEvent(e)
            self.insertPlainText(chars * int(indentation))

        else:
            super().keyPressEvent(e)
Exemple #16
0
class Console(QWidget):
    errorSignal = pyqtSignal(str)
    outputSignal = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__()
        self.parent = parent
        self.pressed = False
        self.font = QFont()
        self.dialog = MessageBox(self)
        # self.font.setFamily(editor["editorFont"])
        self.font.setFamily("Iosevka")
        self.font.setPointSize(12)
        self.layout = QVBoxLayout()

        self.setLayout(self.layout)
        self.output = None
        self.setFocusPolicy(Qt.StrongFocus)
        self.error = None
        self.finished = False
        self.clicked = False

        self.process = QProcess()
        self.state = None
        self.process.readyReadStandardError.connect(self.onReadyReadStandardError)
        self.process.readyReadStandardOutput.connect(self.onReadyReadStandardOutput)
        self.add()  # Add items to the layout

    def ispressed(self):
        return self.pressed

    def added(self):
        self.pressed = True

    def remove(self):
        self.parent.hideFileExecuter()
        self.clicked = True

    def hideTerminalClicked(self):
        return self.clicked

    def onReadyReadStandardError(self):
        try:
            self.error = self.process.readAllStandardError().data().decode()

            self.editor.appendPlainText(self.error)

            self.errorSignal.emit(self.error)
            if self.error == "":
                pass
            else:
                self.error = self.error.split(os.linesep)[-2]
                self.dialog.helpword = str(self.error)
                self.dialog.getHelp(self.parent.parent)
        except IndexError as E:
            print(E, " on line 70 in the file Console.py")

    def onReadyReadStandardOutput(self):
        try:
            self.result = self.process.readAllStandardOutput().data().decode()
        except UnicodeDecodeError as E:
            print(E, " on line 76 in the file Console.py")
        try:
            self.editor.appendPlainText(self.result.strip("\n"))
            self.state = self.process.state()
        except RuntimeError:
            pass

        self.outputSignal.emit(self.result)

    def ifFinished(self, exitCode, exitStatus):
        self.finished = True

    def add(self):
        """Executes a system command."""
        # clear previous text
        self.added()
        self.button = QPushButton("Hide terminal")
        self.button.setFont(QFont("Iosevka", 11))
        self.button.setStyleSheet("""
                height: 20;
                background-color: #212121;

                """)
        self.terminateButton = QPushButton("   Stop")
        self.terminateButton.setIcon(QIcon("resources/square.png"))
        self.terminateButton.setFont(QFont("Iosevka", 11))
        self.terminateButton.clicked.connect(self.terminate)
        self.button.setFixedWidth(120)
        self.h_layout = QHBoxLayout()
        self.editor = Editor(self)
        self.editor.setReadOnly(True)
        self.editor.setFont(self.font)
        self.layout.addWidget(self.button)
        self.layout.addWidget(self.editor)
        self.layout.addWidget(self.terminateButton)
        self.button.clicked.connect(self.remove)

    def run(self, command, path):  # Takes in the command and the path of the file
        os.chdir(os.path.dirname(path))  # We need to change the path to the path where the file is being ran from
        self.editor.clear()
        if self.process.state() == 1 or self.process.state() == 2:
            self.process.kill()
            self.editor.setPlainText("Process already started, terminating")
        else:
            self.process.start(command)

    def terminate(self):
        if self.process.state() == 2:
            self.process.kill()
Exemple #17
0
class Main(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.onStart(choiceIndex)
        self.status = QStatusBar(self)
        # Initializing the main widget where text is displayed
        self.tab = Tabs(self.openFile, app, palette, self)
        self.tabsOpen = []
        self.pic_opened = False

        if file is not None:
            self.openFile(file)
            self.fileNameChange()

        self.dialog = MessageBox(self)

        self.setWindowIcon(QIcon('resources/Python-logo-notext.svg_.png')
                           )  # Setting the window icon

        self.setWindowTitle('PyPad')  # Setting the window title

        self.os = platform.system()

        self.tab.tabs.currentChanged.connect(self.fileNameChange)
        self.search = DocumentSearch()
        self.openterm()
        self.openterminal()
        self.new()
        self.newProject()
        self.findDocument()
        self.openProjectF()
        self.open()
        self.save()
        self.saveAs()
        self.exit()

        self.dir_opened = False
        self._dir = None

        # Without this, the whole layout is broken
        self.setCentralWidget(self.tab)

        self.files = None  # Tracking the current file that is open
        # self.pyFileOpened = False  # Tracking if python file is opened, this is useful to delete highlighting

        self.cFileOpened = False
        self.initUI()  # Main UI

    def fileNameChange(self):
        try:
            currentFileName = self.tab.tabs.currentWidget().baseName
            self.setWindowTitle("PyPad ~ " + str(currentFileName))

        except AttributeError:
            self.setWindowTitle("PyPad ~ ")

    def onStart(self, index):

        if index == 0:
            editor = config0['editor']

        elif index == 1:
            editor = config1['editor']

        elif index == 2:
            editor = config2['editor']

        else:
            editor = config0['editor']

        if editor["windowStaysOnTop"] is True:
            self.setWindowFlags(Qt.WindowStaysOnTopHint)

        else:
            pass

        self.font = QFont()
        self.font.setFamily(editor["editorFont"])

        self.font.setPointSize(editor["editorFontSize"])
        self.tabSize = editor["TabWidth"]

    def initUI(self):

        self.setStatusBar(self.status)  # Initializing the status bar

        self.font.setFixedPitch(True)
        menuFont = QFont()
        menuFont.setFamily(editor["menuFont"])
        menuFont.setPointSize(editor['menuFontSize'])
        menu = self.menuBar()
        menu.setFont(menuFont)
        # Creating the file menu

        fileMenu = menu.addMenu('File')

        # Adding options to the file menu
        # self.setStatusBar(self.status)
        fileMenu.addAction(self.newAct)
        fileMenu.addAction(self.newProjectAct)
        fileMenu.addAction(self.openAct)
        fileMenu.addAction(self.openProjectAct)
        fileMenu.addAction(self.saveAct)
        fileMenu.addAction(self.saveAsAct)
        fileMenu.addSeparator()
        fileMenu.addAction(self.exitAct)

        toolMenu = menu.addMenu('Tools')
        toolMenu.addAction(self.openTermAct)
        toolMenu.addAction(self.openTerminalAct)

        searchDoc = menu.addMenu('Find document')

        searchDoc.addAction(self.findDocumentAct)

        self.showMaximized()

    def open(self):
        self.openAct = QAction('Open...', self)
        self.openAct.setShortcut('Ctrl+O')

        self.openAct.setStatusTip('Open a file')
        self.openAct.triggered.connect(self.openFileFromMenu)

    def new(self):
        self.newAct = QAction('New')
        self.newAct.setShortcut('Ctrl+N')

        self.newAct.setStatusTip('Create a new file')
        self.newAct.triggered.connect(self.newFile)

    def newProject(self):
        self.newProjectAct = QAction('New project')
        self.newProjectAct.setShortcut('Ctrl+Shift+N')

        self.newProjectAct.setStatusTip('Create a new project')
        self.newProjectAct.triggered.connect(self.newProjectFolder)

    def openProjectF(self):
        self.openProjectAct = QAction('Open project')
        self.openProjectAct.setShortcut('Ctrl+Shift+O')

        self.openProjectAct.setStatusTip('Open a project')
        self.openProjectAct.triggered.connect(self.openProject)

    def switchTabs(self):
        if self.tab.tabs.count() - 1 == self.tab.tabs.currentIndex():
            self.tab.tabs.setCurrentIndex(0)
        else:
            self.tab.tabs.setCurrentIndex(self.tab.tabs.currentIndex() + 1)

    def save(self):
        self.saveAct = QAction('Save')
        self.saveAct.setShortcut('Ctrl+S')

        self.saveAct.setStatusTip('Save a file')
        self.saveAct.triggered.connect(self.saveFile)

    def openterm(self):
        self.openTermAct = QAction('Run', self)
        self.openTermAct.setShortcut('Shift+F10')

        self.openTermAct.setStatusTip('Run your code')
        self.openTermAct.triggered.connect(self.execute_file)

    def openterminal(self):
        self.openTerminalAct = QAction("Terminal", self)
        self.openTerminalAct.setShortcut("Ctrl+T")

        self.openTerminalAct.setStatusTip("Open a terminal")
        self.openTerminalAct.triggered.connect(self.realterminal)

    def saveAs(self):
        self.saveAsAct = QAction('Save As...')
        self.saveAsAct.setShortcut('Ctrl+Shift+S')

        self.saveAsAct.setStatusTip('Save a file as')
        self.saveAsAct.triggered.connect(self.saveFileAs)

    def findDocument(self):
        self.findDocumentAct = QAction('Find document')
        self.findDocumentAct.setShortcut('Ctrl+Shift+F')

        self.findDocumentAct.setStatusTip('Find a document')
        self.findDocumentAct.triggered.connect(self.temp)

    def temp(self):
        pass

    def findDocumentFunc(self):

        self.search.run()

    def exit(self):
        self.exitAct = QAction('Quit', self)
        self.exitAct.setShortcut('Ctrl+Q')

        self.exitAct.setStatusTip('Exit application')
        self.exitAct.triggered.connect(qApp.quit)

    def openFileFromMenu(self):
        options = QFileDialog.Options()

        filenames, _ = QFileDialog.getOpenFileNames(
            self,
            'Open a file',
            '',
            'All Files (*);;Python Files (*.py);;Text Files (*.txt)',
            options=options)

        if filenames:  # If file is selected, we can open it
            filename = filenames[0]
            if filename[-3:] in ['gif', 'png', 'jpg', 'bmp'
                                 ] or filename[-4:] in ['jpeg']:
                self.pic_opened = True
            self.openFile(filename)

    def openBrowser(self, url, word):
        widget = Browser(url)
        index = self.tab.tabs.addTab(widget, "Info about: " + str(word))
        self.tab.tabs.setCurrentIndex(index)

    def openFile(self, filename):

        try:
            for index, tabName in enumerate(self.tab.tabCounter):
                with open(filename, 'r+') as file_o:
                    if filename[-3:] in ['gif', 'png', 'jpg', 'bmp'
                                         ] or filename[-4:] in ['jpeg']:
                        self.pic_opened = True
                    else:
                        self.pic_opened = False
                    try:
                        text = file_o.read()

                    except UnicodeDecodeError as E:
                        text = str(E)

                    basename = os.path.basename(filename)
                    if not self.pic_opened:
                        tab = Content(text, filename, basename, self, ex)
                        tab.saved = True
                        tab.modified = False
                    else:
                        tab = Image(filename, basename)
                if tabName == tab.baseName:
                    self.tab.tabs.removeTab(index)

                    self.tab.tabCounter.remove(tab.baseName)
            try:
                with open(filename, 'r+') as file_o:
                    try:
                        if self.pic_opened is not True:
                            text = file_o.read()
                        else:
                            text = None
                    except (FileNotFoundError, UnicodeDecodeError,
                            AttributeError) as E:
                        text = str(E)

            except FileNotFoundError:
                with open(filename, 'w+') as newFileCreated:
                    text = newFileCreated.read()
            basename = os.path.basename(filename)
            if self.pic_opened is True:
                tab = Image(filename, basename)

            else:
                tab = Content(text, filename, basename, self,
                              ex)  # Creating a tab object *IMPORTANT*
                tab.saved = True
                tab.modified = False
            self.tab.tabCounter.append(tab.baseName)
            dirPath = os.path.dirname(filename)
            self.files = filename

            self.tabsOpen.append(self.files)

            index = self.tab.tabs.addTab(
                tab, tab.baseName
            )  # This is the index which we will use to set the current
            self.tab.tabs.setTabToolTip(index, str(tab.fileName))
            if not self.dir_opened:  # If a project isnt opened then we open a directory everytime we open a file
                self.tab.directory.openDirectory(dirPath)

                self.tab.showDirectory()
            else:
                pass

            self.tab.setLayout(self.tab.layout)  # Finally we set the layout

            self.tab.tabs.setCurrentIndex(
                index)  # Setting the index so we could find the current widget

            self.currentTab = self.tab.tabs.currentWidget()

            if self.pic_opened is not True:
                self.currentTab.editor.setFont(self.font)  # Setting the font
                self.currentTab.editor.setFocus(
                )  # Setting focus to the tab after we open it

            self.pic_opened = False
        except (IsADirectoryError, AttributeError, UnboundLocalError,
                PermissionError) as E:
            print(E, " on line 346 in the file main.py")

    def newFile(self):
        text = ""
        if self._dir:
            base_file_name = "Untitled_file_" + str(random.randint(
                1, 100)) + ".py"
            fileName = str(self._dir) + "/" + base_file_name
        else:
            base_file_name = "Untitled_file_" + str(random.randint(
                1, 100)) + ".py"
            current = os.getcwd()
            fileName = current + "/" + base_file_name

        self.pyFileOpened = True
        # Creates a new blank file
        file = Content(text, fileName, base_file_name, self, ex)
        self.tab.splitterH.addWidget(
            self.tab.tabs
        )  # Adding tabs, now the directory tree will be on the left
        self.tab.tabCounter.append(file.fileName)
        self.tab.setLayout(self.tab.layout)  # Finally we set the layout
        index = self.tab.tabs.addTab(
            file, file.baseName
        )  # addTab method returns an index for the tab that was added
        self.tab.tabs.setTabToolTip(index, str(file.fileName))
        self.tab.tabs.setCurrentIndex(
            index)  # Setting focus to the new tab that we created
        widget = self.tab.tabs.currentWidget()

    def newProjectFolder(self):
        self.dialog = MessageBox()
        self.dialog.newProject()

    def openProject(self):

        self._dir = QFileDialog.getExistingDirectory(None, 'Select a folder:',
                                                     '',
                                                     QFileDialog.ShowDirsOnly)

        self.tab.directory.openDirectory(self._dir)
        self.dir_opened = True
        self.tab.showDirectory()

    def saveFile(self):
        try:
            active_tab = self.tab.tabs.currentWidget()
            if self.tab.tabs.count():  # If a file is already opened
                with open(active_tab.fileName, 'w+') as saveFile:
                    saveFile.write(active_tab.editor.text())
                    active_tab.saved = True
                    self.tab.events.look_for_dead_code(
                        active_tab.editor.text())
                    active_tab.modified = False
                    saveFile.close()
                if active_tab.fileName.endswith(".py"):
                    active_tab.editor.updateAutoComplete(active_tab.fileName)
            else:
                options = QFileDialog.Options()
                name = QFileDialog.getSaveFileName(
                    self,
                    'Save File',
                    '',
                    'All Files (*);;Python Files (*.py);;Text Files (*.txt)',
                    options=options)
                fileName = name[0]

                with open(fileName, "w+") as saveFile:
                    active_tab.saved = True
                    active_tab.modified = False
                    self.tabsOpen.append(fileName)
                    saveFile.write(active_tab.editor.text())
                    self.tab.events.look_for_dead_code(
                        active_tab.editor.text())
                    saveFile.close()
                    if fileName.endswith(".py"):
                        active_tab.editor.updateAutoComplete(
                            active_tab.fileName)
            ex.setWindowTitle("PyPad ~ " + str(active_tab.baseName) +
                              " [SAVED]")
            active_tab.tokenize_file()
        except Exception as E:
            print(E, " on line 403 in the file main.py")

    def choose_python(self):
        if self.os == "Windows":
            return "python"

        elif self.os == "Linux":
            return "python3"

        elif self.os == "Darwin":
            return "python3"

    def saveFileAs(self):
        try:
            active_tab = self.tab.tabs.currentWidget()
            if active_tab is not None:
                active_index = self.tab.tabs.currentIndex()

                options = QFileDialog.Options()
                name = QFileDialog.getSaveFileName(
                    self,
                    'Save File',
                    '',
                    'All Files (*);;Python Files (*.py);;Text Files (*.txt)',
                    options=options)
                fileName = name[0]
                with open(fileName, "w+") as saveFile:
                    active_tab.saved = True
                    active_tab.modified = False
                    self.tabsOpen.append(fileName)

                    try:
                        baseName = os.path.basename(fileName)
                    except AttributeError:
                        print("All tabs closed")
                    saveFile.write(active_tab.editor.text())
                    text = active_tab.editor.text()
                    newTab = Content(str(text), fileName, baseName, self, ex)

                    self.tab.tabs.removeTab(
                        active_index
                    )  # When user changes the tab name we make sure we delete the old one
                    index = self.tab.tabs.addTab(
                        newTab, newTab.baseName)  # And add the new one!
                    self.tab.tabs.setTabToolTip(index, str(newTab.fileName))

                    self.tab.tabs.setCurrentIndex(index)
                    newActiveTab = self.tab.tabs.currentWidget()

                    newActiveTab.editor.setFont(self.font)
                    newActiveTab.editor.setFocus()

                    saveFile.close()
                ex.setWindowTitle("PyPad ~ " + str(active_tab.baseName) +
                                  " [SAVED]")

            else:
                print("No file opened")

        except FileNotFoundError:
            print("File dialog closed")

    def realterminal(self):
        """
        Checking if the file executing widget already exists in the splitter layout:
         
        If it does exist, then we're going to replace the widget with the terminal widget, if it doesn't exist then
        just add the terminal widget to the layout and expand the splitter.

        """

        if self.tab.splitterV.indexOf(self.tab.Console) == 1:
            self.tab.splitterV.replaceWidget(
                self.tab.splitterV.indexOf(self.tab.Console),
                self.tab.terminal)
            self.tab.splitterV.setSizes([400, 10])
        else:
            self.tab.showConsole()

    def execute_file(self):
        """
        Checking if the terminal widget already exists in the splitter layout:

        If it does exist, then we're going to replace it, if it doesn't then we're just gonna add our file executer to
        the layout, expand the splitter and run the file.

        Then check if the file executer already exists, but is called again to run the file again

        """
        active_tab = self.tab.tabs.currentWidget()
        python_command = self.choose_python()
        if self.tab.splitterV.indexOf(self.tab.terminal) == 1:
            self.tab.splitterV.replaceWidget(
                self.tab.splitterV.indexOf(self.tab.terminal),
                self.tab.Console)
            self.tab.Console.run(
                "{} ".format(python_command) + active_tab.fileName,
                active_tab.fileName)
            self.tab.splitterV.setSizes([400, 10])

        elif self.tab.splitterV.indexOf(self.tab.Console) == 1:
            self.tab.Console.run(
                "{} ".format(python_command) + active_tab.fileName,
                active_tab.fileName)
        else:
            self.tab.showFileExecuter()
            self.tab.Console.run(
                "{} ".format(python_command) + active_tab.fileName,
                active_tab.fileName)
Exemple #18
0
class Tabs(QWidget):
    def __init__(self, callback, app, palette, parent=None):
        super().__init__()
        self.app = app
        self.parent = parent
        self.palette = palette
        self.terminal = Terminal(self, False)
        self.tool_layout = QVBoxLayout()
        self.tool_layout_bar = QHBoxLayout()
        self.layout = QVBoxLayout(self)
        # Initialize tab screen
        self.tabs = QTabWidget()
        self.events = Events()
        self.tabs.setStyleSheet("""
           QTabWidget::pane { /* The tab widget frame */
                border-top: 0.5px solid #2c2c2c;
            }
            
            QTabWidget::tab-bar {
                
            }
            
            /* Style the tab using the tab sub-control. Note that
                it reads QTabBar _not_ QTabWidget */
            QTabBar::tab {
                background: #212121;
                border-bottom: 2px solid #303030;
                border-bottom-color: #434343;
                min-width: 8ex;
                margin-left: 10px;
                padding-left: 25px;
                padding-right: 20px;
                padding-top: 3px;
                padding-bottom: 3px;
            }
            
            QTabBar::tab:selected, QTabBar::tab:hover {
                background: #212121;
            }
            QToolTip {
                padding: 3px;
                font-family: \"Iosevka\";
                font-size: 14px; 
                color: #FFFFFF;
                background: #2c2c2c;
                
            }
            QTabBar::tab:selected {
                border-bottom-color: #FFFFFF; /* same as pane color */
            }
            """)
        font = QFont(editor['tabFont'])
        font.setPointSize(
            editor["tabFontSize"])  # This is the tab font and font size
        self.tabs.setFont(font)
        self.status = QStatusBar(self)
        self.dialog = MessageBox(self)
        self.tabs.usesScrollButtons()
        self.filelist = []

        self.tabSaved = False

        self.Console = Console(
            self)  # This is the terminal widget and the SECOND thread
        self.directory = Directory(callback, self.app,
                                   self.palette)  # TODO: This is top left
        self.directory.clearSelection()
        self.tabCounter = []
        # Add tabs
        self.tab_layout = QHBoxLayout(
        )  # Create new layout for original tab layout
        self.tab_layout.addWidget(self.tabs)  # Add tab widget to tab layout
        self.search_layout = QHBoxLayout()

        self.tabs.setTabsClosable(True)
        self.tabs.setMovable(
            editor['tabMovable'])  # Let's you make the tabs movable

        if editor[
                'tabShape'] is True:  # If tab shape is true then they have this rounded look
            self.tabs.setTabShape(1)

        else:
            self.tabs.setTabShape(0)  # If false, it has this boxy look

        self.tabs.tabCloseRequested.connect(self.closeTab)

        # Build Layout
        self.layout.addLayout(
            self.tab_layout)  # Adds 'TOP' layout : tab + directory
        self.layout.addLayout(self.search_layout)

        # Creating horizontal splitter
        self.splitterH = QSplitter(Qt.Horizontal)

        # Creating vertical splitter
        self.splitterV = QSplitter(Qt.Vertical)

        self.splitterV2 = QSplitter(Qt.Vertical)

        self.splitterV.addWidget(self.splitterH)
        self.layout.addWidget(self.splitterV)
        self.splitterV.setSizes([400, 10])
        self.setLayout(self.layout)  # Sets layout of QWidget

        self.closeShortcut = QShortcut(
            QKeySequence(editor["closeTabShortcut"]), self)
        self.closeShortcut.activated.connect(self.closeTabShortcut)

        self.getAllOpenTabs = QShortcut(QKeySequence("Ctrl+Shift+W"), self)
        self.getAllOpenTabs.activated.connect(self.getAllOpenTabsFunc)

        currentTab = self.tabs.currentWidget()
        self.layout.addLayout(self.tool_layout)
        self.layout.addWidget(self.splitterV)
        self.hideDirectory()

    @pyqtSlot()
    def closeTabShortcut(self):
        self.index = self.tabs.currentIndex()
        self.closeTab(self.index)

    def getAllOpenTabsFunc(self):
        word = 'import'
        for tab in range(self.tabs.count()):
            file = self.tabs.widget(tab).fileName
            if file not in self.filelist:
                self.filelist.append(file)

        for file in self.filelist:
            openedFileContents = open(file, 'r').read()

    def closeTab(self, index):
        try:

            tab = self.tabs.widget(index)

            if tab.saved is True and tab.modified is False:
                tab.deleteLater()
                self.tabCounter.pop(index)
                self.filelist.pop(index)
                self.tabs.removeTab(index)

            elif tab.modified is True:
                self.dialog.saveMaybe(tab, self.tabCounter, self.tabs, index)

        except (AttributeError, IndexError) as E:
            try:
                tab.deleteLater()
                self.tabCounter.pop(index)
                self.filelist.pop(index)
                self.tabs.removeTab(index)
            except (AttributeError, IndexError) as E:
                print(E, " on line 175 in the file Tabs.py")

    def showDirectory(self):
        self.directory.setVisible(True)
        self.tab_layout.removeWidget(self.tabs)
        self.splitterV2.addWidget(self.directory)
        self.splitterV2.addWidget(self.events)
        self.splitterH.addWidget(self.splitterV2)
        self.splitterH.addWidget(
            self.tabs
        )  # Adding tabs, now the directory tree will be on the left

    def hideDirectory(self):
        self.tab_layout.removeWidget(self.directory)
        self.directory.setVisible(False)

    """
    Because the root layouts are set all you have to do now is just add/remove widgets from the parent layout associated
    This keeps the UI order set as intended as built above when initialized.
    """

    def hideConsole(self):
        self.splitterV.setSizes([0, 0])

    def showConsole(self):
        self.splitterV.addWidget(self.terminal)
        self.splitterV.setSizes([400, 10])
        self.terminal.clicked = False

    def hideFileExecuter(self):
        self.splitterV.setSizes([0, 0])

    def showFileExecuter(self):
        self.splitterV.addWidget(self.Console)
        self.splitterV.setSizes([400, 10])
        self.Console.clicked = False

    def currentTab(self):
        return self.tabs.currentWidget()
Exemple #19
0
class Editor(QPlainTextEdit):
    def __init__(self, parent):
        super().__init__(parent)
        self.lineNumberArea = QLineNumberArea(self)
        self.blockCountChanged.connect(self.updateLineNumberAreaWidth)
        self.updateRequest.connect(self.updateLineNumberArea)
        self.textChanged.connect(self.check)
        self.cursorPositionChanged.connect(self.highlightCurrentLine)
        self.updateLineNumberAreaWidth(0)
        self.parent = parent
        self.font = QFont()
        self.size = 12
        self.dialog = MessageBox()
        self.menu_font = QFont()
        self.menu_font.setFamily("Iosevka")
        self.menu_font.setPointSize(10)
        self.font.setFamily(editor["editorFont"])
        self.font.setPointSize(editor["editorFontSize"])
        self.focused = None

        self.replace_tabs = 4
        self.setWordWrapMode(4)
        self.setFont(self.font)
        self.l = 0
        self.highlightingRules = []
        self.indexes = None

        self.setTabStopWidth(editor["TabWidth"])
        self.createStandardContextMenu()
        self.setWordWrapMode(QTextOption.NoWrap)

    def get_linenumbers(self):
        return self.blockCount()

    def check(self):
        cursor = self.textCursor()
        b = cursor.block()
        if len(b.text()) >= 79:
            print("pep 8 violation on line: " + str(b.blockNumber() + 1))

    def newFile(self):
        """This and most of the functions below will just be wrappers for the functions defined in Main"""
        self.new_action = QAction("New")
        self.new_action.triggered.connect(self.parent.parent.newFile)

    def lineNumberAreaWidth(self):
        digits = 1
        max_value = max(1, self.blockCount())
        while max_value >= 10:
            max_value /= 10
            digits += 1
        space = 10 + self.fontMetrics().width('9') * digits
        return space

    def updateLineNumberAreaWidth(self, _):
        self.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0)

    def updateLineNumberArea(self, rect, dy):
        if dy:
            self.lineNumberArea.scroll(0, dy)
        else:
            self.lineNumberArea.update(0, rect.y(),
                                       self.lineNumberArea.width(),
                                       rect.height())
        if rect.contains(self.viewport().rect()):
            self.updateLineNumberAreaWidth(0)

    def resizeEvent(self, event):
        super().resizeEvent(event)
        cr = self.contentsRect()
        self.lineNumberArea.setGeometry(
            QRect(cr.left(), cr.top(), self.lineNumberAreaWidth(),
                  cr.height()))

    def highlightCurrentLine(self):
        extraSelections = []
        if not self.isReadOnly():
            selection = QTextEdit.ExtraSelection()
            lineColor = QColor("#434343")
            selection.format.setBackground(lineColor)
            selection.format.setProperty(QTextFormat.FullWidthSelection, True)
            selection.cursor = self.textCursor()
            selection.cursor.clearSelection()
            extraSelections.append(selection)
        self.setExtraSelections(extraSelections)

    def lineNumberAreaPaintEvent(self, event):
        painter = QPainter(self.lineNumberArea)

        painter.fillRect(event.rect(), QColor("#303030"))

        block = self.firstVisibleBlock()
        blockNumber = block.blockNumber()
        top = self.blockBoundingGeometry(block).translated(
            self.contentOffset()).top()
        bottom = top + self.blockBoundingRect(block).height()

        # Just to make sure I use the right font
        height = self.fontMetrics().height()

        while block.isValid() and (top <= event.rect().bottom()):
            if block.isVisible() and (bottom >= event.rect().top()):
                number = str(blockNumber + 1)
                painter.setPen(Qt.white)
                painter.drawText(0, top, self.lineNumberArea.width(), height,
                                 Qt.AlignCenter, number)

            block = block.next()
            top = bottom
            bottom = top + self.blockBoundingRect(block).height()
            blockNumber += 1

    def openFile(self):

        self.open_action = QAction("Open")
        self.open_action.triggered.connect(self.parent.parent.openFileFromMenu)

    def runFile(self):

        self.run_action = QAction("Run")
        self.run_action.triggered.connect(self.parent.parent.terminal)

    def contextMenuEvent(self, event):

        menu = QMenu()
        """Initializing actions"""
        self.newFile()
        self.openFile()
        self.runFile()
        print("aa")
        menu.addAction(self.new_action)
        menu.addAction(self.open_action)
        menu.addAction(self.run_action)

        menu.setFont(self.menu_font)

        menu.exec(event.globalPos())
        del menu

    def moveCursorPosBack(self):
        textCursor = self.textCursor()
        textCursorPos = textCursor.position()

        textCursor.setPosition(textCursorPos - 1)
        self.setTextCursor(textCursor)

    def keyPressEvent(self, e):
        textCursor = self.textCursor()
        key = e.key()

        if key == Qt.Key_H:
            # self.parent.completer.wordList
            # TODO: implement dynamic completion
            pass

        textCursorPos = textCursor.position()
        isSearch = (e.modifiers() == Qt.ControlModifier
                    and e.key() == Qt.Key_F)

        if isSearch:
            try:
                currentWidget = self.parent
                currentFile = currentWidget.fileName
                currentEditor = currentWidget.editor

                textCursor = currentEditor.textCursor()
                textCursorPos = textCursor.position()

            except (AttributeError, UnboundLocalError) as E:
                print(E)

            if currentWidget is not None:
                text, okPressed = QInputDialog.getText(self, 'Find',
                                                       'Find what: ')
                if okPressed:
                    if text == "":
                        text = " "
                        self.dialog.noMatch(text)
                    self.searchtext = text
                    try:
                        with open(currentFile, 'r') as file:
                            contents = file.read()
                            self.indexes = list(find_all(contents, text))
                            if len(self.indexes) == 0:
                                self.dialog.noMatch(text)

                    except FileNotFoundError as E:
                        print(E)

        if key == Qt.Key_QuoteDbl:
            self.insertPlainText('"')
            self.moveCursorPosBack()

        if e.modifiers() == Qt.ControlModifier and e.key(
        ) == 61:  # Press Ctrl+Equal key to make font bigger

            self.font.setPointSize(self.size + 1)
            self.font.setFamily(editor["editorFont"])
            self.setFont(self.font)
            self.size += 1
        if e.modifiers() == Qt.ControlModifier and e.key() == 16777217:
            return

        if e.modifiers() == Qt.ControlModifier and e.key(
        ) == 45:  # Press Ctrl+Minus key to make font smaller

            self.font.setPointSize(self.size - 1)

            self.font.setFamily(editor["editorFont"])
            self.setFont(self.font)
            self.size -= 1

        if key == Qt.Key_F3:
            try:
                index = self.indexes[0 + self.l]
                currentWidget = self.parent
                currentFile = currentWidget.fileName
                currentEditor = currentWidget.editor
                textCursor.setPosition(index)
                textCursor.movePosition(textCursor.Right,
                                        textCursor.KeepAnchor,
                                        len(self.searchtext))
                currentEditor.setTextCursor(textCursor)
                self.l += 1
            except IndexError:
                self.l = 0

        if key == 39:
            self.insertPlainText("'")
            self.moveCursorPosBack()

        if key == Qt.Key_BraceLeft:
            self.insertPlainText("}")
            self.moveCursorPosBack()

        if key == Qt.Key_BracketLeft:
            self.insertPlainText("]")
            self.moveCursorPosBack()

        if key == Qt.Key_ParenLeft:
            self.insertPlainText(")")
            self.moveCursorPosBack()

        if key == Qt.Key_ParenRight:
            textCursor = self.textCursor()
            textCursor.select(QTextCursor.WordUnderCursor)
            if textCursor.selectedText(
            ) == "()" or "()" in textCursor.selectedText():
                return

        if key == Qt.Key_BraceRight:
            textCursor = self.textCursor()
            textCursor.select(QTextCursor.WordUnderCursor)
            if textCursor.selectedText == "":
                return

        if key not in [16777217, 16777219, 16777220]:
            super().keyPressEvent(e)
            return

        e.accept()
        cursor = self.textCursor()
        if key == 16777217:  # and self.replace_tabs:
            amount = 4 - self.textCursor().positionInBlock() % 4
            self.insertPlainText(' ' * amount)

        elif key == 16777219 and cursor.selectionStart() == cursor.selectionEnd() and self.replace_tabs and \
                cursor.positionInBlock():
            position = cursor.positionInBlock()
            end = cursor.position()
            start = end - (position % 4)

            if start == end and position >= 4:
                start -= 4

            string = self.toPlainText()[start:end]
            if not len(string.strip()
                       ):  # if length is 0 which is binary for false
                for i in range(end - start):
                    cursor.deletePreviousChar()
            else:
                super().keyPressEvent(e)

        elif key == 16777220:
            end = cursor.position()
            start = end - cursor.positionInBlock()
            line = self.toPlainText()[start:end]
            indentation = len(line) - len(line.lstrip())

            chars = '\t'
            if self.replace_tabs:
                chars = '    '
                indentation /= self.replace_tabs

            if line.endswith(':'):
                if self.replace_tabs:
                    indentation += 1

            super().keyPressEvent(e)
            self.insertPlainText(chars * int(indentation))

        else:
            super().keyPressEvent(e)
Exemple #20
0
    def __init__(self, callback, app, palette, parent=None):
        super().__init__()
        self.app = app
        self.parent = parent
        self.palette = palette
        self.terminal = Terminal(self, False)
        self.tool_layout = QVBoxLayout()
        self.tool_layout_bar = QHBoxLayout()
        self.layout = QVBoxLayout(self)
        # Initialize tab screen
        self.tabs = QTabWidget()
        self.events = Events()
        self.tabs.setStyleSheet("""
           QTabWidget::pane { /* The tab widget frame */
                border-top: 0.5px solid #2c2c2c;
            }
            
            QTabWidget::tab-bar {
                
            }
            
            /* Style the tab using the tab sub-control. Note that
                it reads QTabBar _not_ QTabWidget */
            QTabBar::tab {
                background: #212121;
                border-bottom: 2px solid #303030;
                border-bottom-color: #434343;
                min-width: 8ex;
                margin-left: 10px;
                padding-left: 25px;
                padding-right: 20px;
                padding-top: 3px;
                padding-bottom: 3px;
            }
            
            QTabBar::tab:selected, QTabBar::tab:hover {
                background: #212121;
            }
            QToolTip {
                padding: 3px;
                font-family: \"Iosevka\";
                font-size: 14px; 
                color: #FFFFFF;
                background: #2c2c2c;
                
            }
            QTabBar::tab:selected {
                border-bottom-color: #FFFFFF; /* same as pane color */
            }
            """)
        font = QFont(editor['tabFont'])
        font.setPointSize(
            editor["tabFontSize"])  # This is the tab font and font size
        self.tabs.setFont(font)
        self.status = QStatusBar(self)
        self.dialog = MessageBox(self)
        self.tabs.usesScrollButtons()
        self.filelist = []

        self.tabSaved = False

        self.Console = Console(
            self)  # This is the terminal widget and the SECOND thread
        self.directory = Directory(callback, self.app,
                                   self.palette)  # TODO: This is top left
        self.directory.clearSelection()
        self.tabCounter = []
        # Add tabs
        self.tab_layout = QHBoxLayout(
        )  # Create new layout for original tab layout
        self.tab_layout.addWidget(self.tabs)  # Add tab widget to tab layout
        self.search_layout = QHBoxLayout()

        self.tabs.setTabsClosable(True)
        self.tabs.setMovable(
            editor['tabMovable'])  # Let's you make the tabs movable

        if editor[
                'tabShape'] is True:  # If tab shape is true then they have this rounded look
            self.tabs.setTabShape(1)

        else:
            self.tabs.setTabShape(0)  # If false, it has this boxy look

        self.tabs.tabCloseRequested.connect(self.closeTab)

        # Build Layout
        self.layout.addLayout(
            self.tab_layout)  # Adds 'TOP' layout : tab + directory
        self.layout.addLayout(self.search_layout)

        # Creating horizontal splitter
        self.splitterH = QSplitter(Qt.Horizontal)

        # Creating vertical splitter
        self.splitterV = QSplitter(Qt.Vertical)

        self.splitterV2 = QSplitter(Qt.Vertical)

        self.splitterV.addWidget(self.splitterH)
        self.layout.addWidget(self.splitterV)
        self.splitterV.setSizes([400, 10])
        self.setLayout(self.layout)  # Sets layout of QWidget

        self.closeShortcut = QShortcut(
            QKeySequence(editor["closeTabShortcut"]), self)
        self.closeShortcut.activated.connect(self.closeTabShortcut)

        self.getAllOpenTabs = QShortcut(QKeySequence("Ctrl+Shift+W"), self)
        self.getAllOpenTabs.activated.connect(self.getAllOpenTabsFunc)

        currentTab = self.tabs.currentWidget()
        self.layout.addLayout(self.tool_layout)
        self.layout.addWidget(self.splitterV)
        self.hideDirectory()
Exemple #21
0
class Editor(QPlainTextEdit):

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

        self.parent = parent
        self.font = QFont()
        self.size = 12
        self.dialog = MessageBox()
        self.menu_font = QFont()
        self.menu_font.setFamily("Iosevka")
        self.menu_font.setPointSize(10)
        self.font.setFamily(editor["editorFont"])
        self.font.setPointSize(editor["editorFontSize"])
        self.focused = None

        self.replace_tabs = 4
        self.setWordWrapMode(4)
        self.setFont(self.font)
        self.l = 0
        self.highlightingRules = []
        self.indexes = None

        self.setTabStopWidth(editor["TabWidth"])
        self.createStandardContextMenu()
        self.setWordWrapMode(QTextOption.NoWrap)

    def newFile(self):
        """This and most of the functions below will just be wrappers for the functions defined in Main"""
        self.new_action = QAction("New")
        self.new_action.triggered.connect(self.parent.parent.newFile)

    def openFile(self):

        self.open_action = QAction("Open")
        self.open_action.triggered.connect(self.parent.parent.openFileFromMenu)

    def runFile(self):

        self.run_action = QAction("Run")
        self.run_action.triggered.connect(self.parent.parent.Terminal)

    def contextMenuEvent(self, event):

        menu = QMenu()
        """Initializing actions"""
        self.newFile()
        self.openFile()
        self.runFile()

        menu.addAction(self.new_action)
        menu.addAction(self.open_action)
        menu.addAction(self.run_action)

        menu.setFont(self.menu_font)

        menu.exec(event.globalPos())
        del menu

    def moveCursorPosBack(self):
        textCursor = self.textCursor()
        textCursorPos = textCursor.position()

        textCursor.setPosition(textCursorPos - 1)
        self.setTextCursor(textCursor)

    def keyPressEvent(self, e):
        textCursor = self.textCursor()
        key = e.key()

        if key == Qt.Key_H:
            # self.parent.completer.wordList
            # TODO: implement dynamic completion
            pass

        textCursorPos = textCursor.position()
        isSearch = (e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_F)

        if isSearch:
            try:
                currentWidget = self.parent
                currentFile =  currentWidget.fileName
                currentEditor = currentWidget.editor

                textCursor = currentEditor.textCursor()
                textCursorPos = textCursor.position()

            except (AttributeError, UnboundLocalError) as E:
                print(E)

            if currentWidget is not None:
                text, okPressed = QInputDialog.getText(self, 'Find', 'Find what: ')
                if okPressed:
                    if text == "":
                        text = " "
                        self.dialog.noMatch(text)
                    self.searchtext = text
                    try:
                        with open(currentFile, 'r') as file:
                            contents = file.read()
                            self.indexes = list(find_all(contents, text))
                            if len(self.indexes) == 0:
                                self.dialog.noMatch(text)

                    except FileNotFoundError as E:
                        print(E)

        if key == Qt.Key_QuoteDbl:
            self.insertPlainText('"')
            self.moveCursorPosBack()

        if (e.modifiers() == Qt.ControlModifier and e.key() == 61):  # Press Ctrl+Equal key to make font bigger

            self.font.setPointSize(self.size + 1)
            self.font.setFamily(editor["editorFont"])
            self.setFont(self.font)
            self.size += 1

        if (e.modifiers() == Qt.ControlModifier and e.key() == 45): # Press Ctrl+Minus key to make font smaller

            self.font.setPointSize(self.size - 1)

            self.font.setFamily(editor["editorFont"])
            self.setFont(self.font)
            self.size -= 1

        if key == Qt.Key_F3:
            try:
                index = self.indexes[0 + self.l]
                currentWidget = self.parent
                currentFile =  currentWidget.fileName
                currentEditor = currentWidget.editor
                textCursor.setPosition(index)
                textCursor.movePosition(textCursor.Right, textCursor.KeepAnchor, len(self.searchtext))
                currentEditor.setTextCursor(textCursor)
                self.l += 1
            except IndexError:
                self.l = 0

        if key == 39:
            self.insertPlainText("'")
            self.moveCursorPosBack()

        if key == Qt.Key_BraceLeft:
            self.insertPlainText("}")
            self.moveCursorPosBack()

        if key == Qt.Key_BracketLeft:
            self.insertPlainText("]")
            self.moveCursorPosBack()

        if key == Qt.Key_ParenLeft:

            self.insertPlainText(")")
            self.moveCursorPosBack()

        if key == Qt.Key_ParenRight:
            textCursor = self.textCursor()
            textCursor.select(QTextCursor.WordUnderCursor)
            if textCursor.selectedText() == "()" or "()" in textCursor.selectedText():
                return

        if key == Qt.Key_BraceRight:
            textCursor = self.textCursor()
            textCursor.select(QTextCursor.WordUnderCursor)
            if textCursor.selectedText == "":
                return

        if key not in [16777217, 16777219, 16777220]:

            super().keyPressEvent(e)
            return

        e.accept()
        cursor = self.textCursor()
        if key == 16777217: # and self.replace_tabs:
            amount = 4 - self.textCursor().positionInBlock() % 4
            self.insertPlainText(' ' * amount)

        elif key == 16777219 and cursor.selectionStart() == cursor.selectionEnd() and self.replace_tabs and \
                cursor.positionInBlock():
            position = cursor.positionInBlock()
            end = cursor.position()
            start = end - (position % 4)

            if start == end and position >= 4:
                start -= 4

            string = self.toPlainText()[start:end]
            if not len(string.strip()): # if length is 0 which is binary for false
                for i in range(end - start):
                    cursor.deletePreviousChar()
            else:
                super().keyPressEvent(e)

        elif key == 16777220:
            end = cursor.position()
            start = end - cursor.positionInBlock()
            line = self.toPlainText()[start:end]
            indentation = len(line) - len(line.lstrip())

            chars = '\t'
            if self.replace_tabs:
                chars = '    '
                indentation /= self.replace_tabs

            if line.endswith(':'):
                if self.replace_tabs:
                    indentation += 1

            super().keyPressEvent(e)
            self.insertPlainText(chars * int(indentation))

        else:
            super().keyPressEvent(e)
Exemple #22
0
 def newProjectFolder(self):
     self.dialog = MessageBox()
     self.dialog.newProject()
Exemple #23
0
class Editor(QsciScintilla):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.fileName = None
        self.parent = parent
        self.debugging = False
        self.line = None
        self.column = None

        self.wordlist = []
        self.searchtext = None

        self.font = QFont()
        self.font.setFamily("Inconsolata")
        self.pointSize = 12  # TODO: Make this customizable
        self.tabWidth = 4  # TODO: Make this customizable
        self.font.setPointSize(self.pointSize)
        self.dialog = MessageBox(self)
        self.verticalScrollBar().setStyleSheet("""
            background-color: transparent;
            """)

        self.horizontalScrollBar().setStyleSheet("""
            background-color: transparent;
            """)

        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setCaretForegroundColor(QColor("#FFFFFF"))
        self.setEdgeColumn(121)
        self.setEdgeMode(1)
        self.setEdgeColor(QColor("#8c8c8c"))
        self.setFont(self.font)
        self.setMarginSensitivity(1, True)
        self.markerDefine(QsciScintilla.RightArrow, 8)
        self.setMarkerBackgroundColor(QColor('#FF0000'), 8)
        self.indicator_number = 0
        self.indicator_value = 222
        self.indicator_color = QColor("#FF0000")
        self.draw_under_text = True
        # Initializing some stuff
        self.set_brace_colors(QColor("#98b4f9"), QColor("#edf40e"),
                              QColor("#98b4f9"), QColor("red"))

        self.cursorPositionChanged.connect(self.change_col)
        self.textChanged.connect(self.check_lines)

        self.set_linenumbers(QFontMetrics(self.font))
        self.setFoldMarginColors(QColor("#212121"), QColor("#212121"))
        self.set_indentation_settings(self.tabWidth)

    def set_up_tooltips(self):
        self.setCallTipsStyle(QsciScintilla.CallTipsNoContext)
        self.setCallTipsVisible(0)

        self.setCallTipsPosition(QsciScintilla.CallTipsAboveText)
        self.setCallTipsBackgroundColor(QColor("#FF0000"))

        self.setCallTipsForegroundColor(QColor("#FF0000"))
        self.setCallTipsHighlightColor(QColor("#FF0000"))

    def set_brace_colors(self,
                         matched_B=None,
                         matched_F=None,
                         unmatched_B=None,
                         unmatched_F=None):

        self.setMatchedBraceBackgroundColor(matched_B)
        self.setMatchedBraceForegroundColor(matched_F)
        self.setUnmatchedBraceBackgroundColor(unmatched_B)
        self.setUnmatchedBraceForegroundColor(unmatched_F)

        self.setBraceMatching(QsciScintilla.SloppyBraceMatch)

    def set_linenumbers(self, fontmetrics):
        self.setMarginsFont(self.font)

        self.setMarginWidth(0, fontmetrics.width("00000"))
        self.setMarginLineNumbers(0, True)

        self.setMarginsBackgroundColor(QColor("#212121"))
        self.setMarginsForegroundColor(QColor("#FFFFFF"))

    def set_indentation_settings(self, tab_width):
        self.setIndentationsUseTabs(False)

        self.setTabWidth(tab_width)

        self.SendScintilla(QsciScintilla.SCI_SETUSETABS, False)

        self.setAutoIndent(True)
        self.setTabIndents(True)

    def check_lines(self):
        line_n = self.lines()
        for i in range(line_n):
            if self.lineLength(i) > 121:
                # TODO: Make a character format or something
                pass
                #  print("Line over 121 characters on line", str(i+1))
                # self.setCursorPosition(i, 120)

    def python_highlighter(self):
        self.lexer = PythonLexer()
        self.lexer.setFoldComments(True)
        self.setCaretLineVisible(True)

        self.setDefaultSettings(self.lexer)
        self.setPythonAutocomplete()
        self.setFold()

    def json_highlighter(self):
        lexer = QsciLexerJSON()
        self.setDefaultSettings(lexer)

    def c_highlighter(self):
        lexer = QsciLexerCPP()

        self.setDefaultSettings(lexer)

    def setDefaultSettings(self, lexer):
        self.setAutoIndent(True)
        lexer.setFont(self.font)

        lexer.setColor(QColor('white'), 0)  # default
        lexer.setColor(QColor('#6B6E6C'), PythonLexer.Comment)  # = 1
        lexer.setColor(QColor('#ADD4FF'), 2)  # Number = 2
        lexer.setColor(QColor('#38ef7d'), 3)  # DoubleQuotedString
        lexer.setColor(QColor('#38ef7d'), 4)  # SingleQuotedString
        lexer.setColor(QColor('#F6DC74'), 5)  # Keyword
        lexer.setColor(QColor('#38ef7d'), 6)  # TripleSingleQuotedString
        lexer.setColor(QColor('#38ef7d'), 7)  # TripleDoubleQuotedString
        lexer.setColor(QColor('#74F6C3'), 8)  # ClassName
        lexer.setColor(QColor('#FF6666'), 9)  # FunctionMethodName
        lexer.setColor(QColor('magenta'), 10)  # Operator
        lexer.setColor(QColor('white'), 11)  # Identifier
        lexer.setColor(QColor('gray'), 12)  # CommentBlock
        lexer.setColor(QColor('#a8ff78'), 13)  # UnclosedString
        lexer.setColor(QColor('gray'), 14)  # HighlightedIdentifier
        lexer.setColor(QColor('#FF00E7'), 15)  # Decorator

        lexer.setFont(QFont("Iosevka", weight=QFont.Bold), 5)
        self.setCaretLineBackgroundColor(QColor("#3C3B3F"))
        self.setLexer(lexer)

    def setPythonAutocomplete(self):
        self.autocomplete = QsciAPIs(self.lexer)
        self.keywords = wordList

        for word in self.keywords:
            self.autocomplete.add(word)

        self.setAutoCompletionThreshold(2)

        self.setAutoCompletionSource(QsciScintilla.AcsAPIs)
        self.updateAutoComplete(self.parent.fileName)

        self.autocomplete.prepare()

    def setFold(self):
        # setup Fold Styles for classes and functions ...
        x = self.FoldStyle(self.FoldStyle(5))
        # self.textPad.folding()
        if not x:
            self.foldAll(False)

        self.setFolding(x)
        # self.textPad.folding()

    def unsetFold(self):
        self.setFolding(0)

    def updateAutoComplete(self, file_path=None):

        for i in tokenize(file_path):
            for j in i:
                if j not in self.wordlist:
                    self.wordlist.append(j)
        for word in self.wordlist:
            self.autocomplete.add(word)

        self.autocomplete.prepare()

    def change_col(self, line,
                   column):  # Responsible for changing the column bar.
        self.line = line
        self.column = column

    def check_if_func(self, word):  # Checks if a word is a built in function
        word_array = list(word)
        for wo in word_array:
            if wo in ["{", "}", "'", '"', "[", "]", "(", ")"]:
                word_array.remove(wo)
        for w in funcList:
            if w == "".join(word_array):
                return True

    def check_if_error(self, word):
        if word in errorList:  # This is the list where all possible errors are defined
            return True

    def keyReleaseEvent(self, e):
        if e.key() == Qt.Key_Return:
            try:
                self.updateAutoComplete(self.parent.fileName)
            except AttributeError as E:
                print(E, "on line 210 in TextEditor.py")

        if e.key() == Qt.Key_Backspace:
            pass

    def mousePressEvent(self, e):
        super().mousePressEvent(e)

        if QGuiApplication.queryKeyboardModifiers() == Qt.ControlModifier:
            word = self.wordAtLineIndex(self.getCursorPosition()[0],
                                        self.getCursorPosition()[1])
            print(word)
            if self.check_if_func(word):
                url = "https://docs.python.org/3/library/functions.html#" + word
                self.parent.parent.openBrowser(
                    url, word)  # Runs the openBrowser function in Main class
            elif self.check_if_error(word):
                url = "https://docs.python.org/3/library/exceptions.html#" + word
                print(url)

                self.parent.parent.openBrowser(url, word)

    def keyPressEvent(self, e):
        if e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_F:
            text, okPressed = QInputDialog.getText(self, 'Find', 'Find what: ')

            self.setSelectionBackgroundColor(QColor("#6be585"))

            if okPressed:
                if text == "":
                    text = " "
                    self.dialog.noMatch(text)

                self.searchtext = text
                """
                This is the way to implement a search function using QScintilla 
                http://pyqt.sourceforge.net/Docs/QScintilla2/classQsciScintilla.html#a37ac2bea94eafcfa639173557a821200
                """

                if self.findFirst(self.searchtext, False, True, False, True,
                                  True, -1, -1, True, False):
                    pass
                else:
                    self.dialog.noMatch(self.searchtext)

        if e.key() == Qt.Key_F3:
            self.findNext()
            self.setSelectionBackgroundColor(QColor("#6be585"))

        if e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_L:
            self.setCursorPosition(self.line, self.column + 1)
            return
        if e.modifiers() == Qt.ControlModifier and e.key() == 77:

            self.setCursorPosition(self.line + 1, self.column)
            return
        if e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_J:
            self.setCursorPosition(self.line, self.column - 1)

        if e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_I:
            self.setCursorPosition(self.line - 1, self.column)

        if e.modifiers() == Qt.ControlModifier and e.key() == Qt.Key_T:
            self.parent.parent.realterminal()
            return

        super().keyPressEvent(e)