Ejemplo n.º 1
0
    def find(self, checked):
        print(checked)

        # Grab the parent's text
        text = self.parent.text_doc.toPlainText()

        # And the text to find
        query = self.findField.toPlainText()

        # By default regexes are case sensitive but usually a search isn't
        # case sensitive by default, so we need to switch this around here
        flags = 0 if self.caseSens.isChecked() else re.I

        # Compile the pattern
        pattern = re.compile(query, flags)

        # If the last match was successful, start at position after the last
        # match's start, else at 0
        start = self.lastMatch.start() + 1 if self.lastMatch else 0

        # The actual search
        self.lastMatch = pattern.search(text, start)

        if self.lastMatch:
            start = self.lastMatch.start()
            end = self.lastMatch.end()

            lineColor = QtGui.QColor(QtCore.Qt.green).lighter(160)
            Highlighter.highlightText(self.parent.text_doc, start, end,
                                      lineColor)

        else:
            # if the search was unsuccessful
            print("Nothing was found")
Ejemplo n.º 2
0
class Widget(QTextEdit):
    result = []

    def __init__(self, left, top, width, height, parent=None):
        super().__init__(parent)
        self.left = left
        self.top = top
        self.width = width
        self.height = height
        self.setParent(parent)
        self.initWidget()
        self.highLighter = Highlighter(self.document())

        # self.highLighter = Highlighter(self.document())

        #    self.setStyleSheet("""QTextEdit{
        # font-family:'Consolas';
        # color: #ccc;
        # background-color: #2b2b2b;}""")

    def returnResult(self, res):
        self.highLighter.getResult(res)

    def initWidget(self):
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.show()

    def setText(self, text):
        super().setText(text)

    def getText(self):
        super().toPlainText()
Ejemplo n.º 3
0
    def __init__(self, *args, **kwargs):
        super(EditorBase, self).__init__(*args, **kwargs)

        # Make sure editor always has a monospace font.
        self.__zoom = 0
        self.setFont()

        self.__highlighter = Highlighter(self.document())
        self.__highlighter.setRules(PythonHighlighter)

        # Set general document option
        option = self.document().defaultTextOption()
        option.setFlags(option.flags() | option.IncludeTrailingSpaces |
                        option.AddSpaceForLineAndParagraphSeparators)

        if self.indentUsingSpaces():
            option.setFlags(option.flags() | option.ShowTabsAndSpaces)

        self.document().setDefaultTextOption(option)

        # View Settings
        # self.setShowWhitespace()
        # self.setShowLineEndings()
        # self.setWrap()
        # self.setHighlightCurrentLine()
        # self.setLongLineIndicatorPosition()

        # So that graphical elements wont break.
        self.cursorPositionChanged.connect(self.viewport().update)
Ejemplo n.º 4
0
    def __init__(self, player_key):

        self.level = None
        self.player = None
        self.player_key = player_key
        self.objects = []

        self.ui = UI(self)

        self.turn_tracker = TurnTracker(self)
        self.turn = 'player'
        self.active_ability = None

        self.effect_tracker = EffectTracker(self)

        self.clock = pygame.time.Clock()
        self.tick = 0

        self.pointer = Pointer(self)
        self.highlighter = Highlighter(self)

        self.sub_screen = pygame.Surface((720, 720)).convert()

        self.game_display = GameDisplay(self)
        self.screen_mode = 'zoomed'

        self.zoomed_sub_screen = pygame.Surface((19 * 16, 15 * 24)).convert()
        self.zoomed_sub_screen_scale = pygame.Surface(
            (19 * 16 * 2, 15 * 24 * 2)).convert()
        self.zoomed_sub_screen_scale_rect = self.zoomed_sub_screen_scale.get_rect(
        )
        self.zoomed_sub_screen_scale_rect.topleft = (56, 0)
Ejemplo n.º 5
0
    def __init__(self):
        super().__init__()

        self.title('Python Text Editor v3')
        self.geometry('800x600')

        self.foreground = 'black'
        self.background = 'lightgrey'
        self.text_foreground = 'black'
        self.text_background = 'white'

        self.load_scheme_file('schemes/default.yaml')
        self.configure_ttk_elements()

        self.font_size = 15
        self.font_family = "Ubuntu Mono"
        self.load_font_file('schemes/font.yaml')

        self.text_area = TextArea(self,
                                  bg=self.text_background,
                                  fg=self.text_foreground,
                                  undo=True,
                                  font=(self.font_family, self.font_size))

        self.scrollbar = ttk.Scrollbar(orient="vertical",
                                       command=self.scroll_text)
        self.text_area.configure(yscrollcommand=self.scrollbar.set)

        self.line_numbers = LineNumbers(self,
                                        self.text_area,
                                        bg="grey",
                                        fg="white",
                                        width=1)
        self.highlighter = Highlighter(self.text_area, 'languages/python.yaml')

        self.menu = tk.Menu(self, bg=self.background, fg=self.foreground)
        self.all_menus = [self.menu]

        sub_menu_items = ["file", "edit", "tools", "help"]
        self.generate_sub_menus(sub_menu_items)
        self.configure(menu=self.menu)

        self.right_click_menu = tk.Menu(self,
                                        bg=self.background,
                                        fg=self.foreground,
                                        tearoff=0)
        self.right_click_menu.add_command(label='Cut', command=self.edit_cut)
        self.right_click_menu.add_command(label='Copy', command=self.edit_copy)
        self.right_click_menu.add_command(label='Paste',
                                          command=self.edit_paste)
        self.all_menus.append(self.right_click_menu)

        self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.line_numbers.pack(side=tk.LEFT, fill=tk.Y)
        self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

        self.bind_events()

        self.open_file = ''
Ejemplo n.º 6
0
 def load_syntax_highlighting_file(self):
     syntax_file = filedialog.askopenfilename(filetypes=[("YAML file",
                                                          ("*.yaml",
                                                           "*.yml"))])
     if syntax_file:
         self.highlighter.clear_highlight()
         self.highlighter = Highlighter(self.text_area, syntax_file)
         self.highlighter.force_highlight()
Ejemplo n.º 7
0
 def load_syntax_highlighting(self):
     syntax_file = filedialog.askopenfilename(filetypes=[('YAML file',
                                                          ('*.yaml',
                                                           '*.yml'))])
     if syntax_file:
         self.highlighter.clear_highlight()
         self.highlighter = Highlighter(self.text_area, syntax_file)
         self.highlighter.force_highlight()
Ejemplo n.º 8
0
 def terminal_mode(self, event=None):
     if self.thee_mode == 1:
         self.line_numbers.destroy()
     self.text_area.config(state=tk.NORMAL, tabs=4)
     self.text_area.delete('1.0', tk.END)
     self.text_area.insert(tk.END, self.terminal_mode_buffer)
     self.terminal.writeLoop()
     self.highlighter = Highlighter(self.text_area)
     self.thee_mode = 2
Ejemplo n.º 9
0
 def __init__(self, left, top, width, height, parent=None):
     super().__init__(parent)
     self.left = left
     self.top = top
     self.width = width
     self.height = height
     self.setParent(parent)
     self.initWidget()
     self.highLighter = Highlighter(self.document())
Ejemplo n.º 10
0
def highlight():
    data = request.get_json()
    highlight = Highlighter(data['filename'], data['code'])
    return_dict = {
        'highlighted_code': highlight.get_highlighted_code(),
        'css_class': highlight.get_stylesheet_content(),
        'id_name': highlight.get_css_id_name(),
        'success': True,
            }
    return jsonify(return_dict)
Ejemplo n.º 11
0
    def __init__(self):
        super().__init__()
        self.text_area = TextArea(self, bg="white", fg="black", undo=True)
        self.scrollbar = ttk.Scrollbar(orient="vertical",
                                       command=self.scroll_text)
        self.text_area.configure(yscrollcommand=self.scrollbar.set)
        self.scrollbar.pack(side=tk.LEFT, fill=tk.Y)
        self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

        self.line_numbers = LineNumbers(self,
                                        self.text_area,
                                        bg="grey",
                                        fg="white",
                                        width=1)
        self.highlighter = Highlighter(self.text_area, 'languages/python.yaml')

        # first_100_numbers = [str(n+1) for n in range(100)]
        # self.line_numbers.insert(1.0, "\n".join(first_100_numbers))
        # self.line_numbers.configure(state="disabled", width=3)

        self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.line_numbers.pack(side=tk.LEFT, fill=tk.Y)
        self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

        self.bind_events()
Ejemplo n.º 12
0
    def __init__(self, parent=None):

        super(Editor, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.file_path = None
        self.proc = QProcess()

        Highlighter(self.ui.text_editor)

        self.ui.actionRun.triggered.connect(self.run_triggered)

        self.ui.actionOpen.triggered.connect(self.open_triggered)

        self.ui.actionSave.triggered.connect(self.save_triggered)

        self.ui.actionClose.triggered.connect(self.close_triggered)

        self.proc.started.connect(self.process_started)

        self.proc.errorOccurred.connect(self.process_error_occurred)

        self.proc.readyReadStandardOutput.connect(
            self.process_ready_read_standard_output)

        self.proc.finished.connect(self.process_finished)

        self.proc.readyReadStandardError.connect(
            self.process_ready_read_standard_error)
Ejemplo n.º 13
0
    def __init__(self, settings, parent_textEdit):

        sys.excepthook = exception_handler
        QtWidgets.QDialog.__init__(self)
        self.settings = settings
        self.parent_textEdit = parent_textEdit
        self.queryTime = ""
        self.queryFilters = ""
        textEditSql = ""

        # Set up the user interface from Designer.
        self.ui = Ui_Dialog_sql()
        self.ui.setupUi(self)
        #self.setWindowTitle("Query: " + self.queryname)
        self.ui.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        highlighter = Highlighter(self.ui.textEdit_sql)
        self.ui.textEdit_sql.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.textEdit_sql.customContextMenuRequested.connect(self.sql_menu)
        # fill textEdit_sql from queryname
        self.ui.textEdit_sql.setText(textEditSql)
        self.ui.tableWidget_results.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.tableWidget_results.customContextMenuRequested.connect(
            self.table_menu)

        # Add tables and fields to treeWidget
        self.get_schema_update_treeWidget()
        self.ui.treeWidget.itemClicked.connect(self.get_item)
        self.ui.pushButton_runSQL.clicked.connect(self.run_SQL)
        self.ui.pushButton_export.clicked.connect(self.export_file)
        self.ui.splitter.setSizes([20, 180])
        self.ui.splitter_2.setSizes([10, 290])
Ejemplo n.º 14
0
    def editor_mode(self, event=None):
        self.text_area.config(state=tk.NORMAL, tabs=4)
        self.text_area.delete('1.0', tk.END)
        self.text_area.insert(tk.END, self.editor_mode_buffer)
        self.highlighter = Highlighter(self.text_area)
        self.thee_mode = 1

        self.line_numbers = LineNumbers(self.frame1, self.text_area)
        self.line_numbers.config(bg=self.text_background,
                                 width=len(self.line_numbers.line_number) * 10,
                                 highlightthickness=0)
        self.line_numbers.grid(row=0, column=0, sticky='ns')

        self.status_bar1.set("Line %d, Column %d" % (self.line, self.column))
        self.status_bar3.set("%s" % self.file_name)
        self.status_bar4.set("Spaces: %d" % self.spaces)
        self.status_bar5.set("%s" % self.status)
Ejemplo n.º 15
0
def main():
    highlighter = Highlighter() 
    queries = make_queries_dict()

    if FLAGS.input_file is not None:
        scrape_document_file(FLAGS.input_file, queries, highlighter)
    else:
        scrape_query_file(queries[FLAGS.query], highlighter)
 def test_highlight_doc(self):
     highlighted_result = Highlighter.highlight_doc(self.doc, self.query)
     msg = "\nhighlighted_result =\n" + highlighted_result
     expected_result = " [[HIGHLIGHT]]tacos[[HIGHLIGHT]] I've ever had were from Panchos. "
     expected_result = expected_result + "This sentence is about nothing. Great [[HIGHLIGHT]]"
     expected_result = expected_result + "tacos burritos[[HIGHLIGHT]], and [[HIGHLIGHT]]"
     expected_result = expected_result + "enchaladas[[HIGHLIGHT]]. Bean [[HIGHLIGHT]]burritos[[HIGHLIGHT]]"
     msg = msg + "\nexpected_result = \n" + expected_result
     self.assertEquals(expected_result, highlighted_result, msg)
Ejemplo n.º 17
0
    def __init__(self, app, parent_textEdit):

        sys.excepthook = exception_handler
        QtWidgets.QDialog.__init__(self)
        self.app = app
        self.parent_textEdit = parent_textEdit
        self.queryTime = ""
        self.queryFilters = ""
        textEditSql = ""

        # Set up the user interface from Designer.
        self.ui = Ui_Dialog_sql()
        self.ui.setupUi(self)
        try:
            w = int(self.app.settings['dialogsql_w'])
            h = int(self.app.settings['dialogsql_h'])
            if h > 50 and w > 50:
                self.resize(w, h)
        except:
            pass
        self.setWindowFlags(self.windowFlags()
                            & ~QtCore.Qt.WindowContextHelpButtonHint)
        font = 'font: ' + str(self.app.settings['fontsize']) + 'pt '
        font += '"' + self.app.settings['font'] + '";'
        self.setStyleSheet(font)
        #self.setWindowTitle("Query: " + self.queryname)
        self.ui.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        highlighter = Highlighter(self.ui.textEdit_sql)
        self.ui.textEdit_sql.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.textEdit_sql.customContextMenuRequested.connect(self.sql_menu)
        # fill textEdit_sql from queryname
        self.ui.textEdit_sql.setText(textEditSql)
        self.ui.tableWidget_results.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.tableWidget_results.customContextMenuRequested.connect(
            self.table_menu)

        # Add tables and fields to treeWidget
        self.get_schema_update_treeWidget()
        self.ui.treeWidget.itemClicked.connect(self.get_item)
        self.ui.pushButton_runSQL.clicked.connect(self.run_SQL)
        self.ui.pushButton_export.clicked.connect(self.export_file)
        self.ui.splitter.setSizes([20, 180])
        try:
            s0 = int(self.app.settings['dialogsql_splitter_h0'])
            s1 = int(self.app.settings['dialogsql_splitter_h1'])
            if s0 > 10 and s1 > 10:
                self.ui.splitter.setSizes([s0, s1])
        except:
            pass
        self.ui.splitter_2.setSizes([10, 290])
        try:
            s0 = int(self.app.settings['dialogsql_splitter_v0'])
            s1 = int(self.app.settings['dialogsql_splitter_v1'])
            if s0 > 10 and s1 > 10:
                self.ui.splitter_2.setSizes([s0, s1])
        except:
            pass
 def setUp(self):
     doc = "This is my review on Panchos Mexican Restaurant. This is only a "
     doc = doc + "test of the emergency broadcasting system. The best "
     doc = doc + "tacos I've ever had were from Panchos. This sentence is "
     doc = doc + "about nothing. Great tacos, burritos, and enchaladas. "
     doc = doc + "Bean burritos are also good. Lots more filler text here. "
     doc = doc + "The filler text in this sentence is muy bueno. Remember to "
     doc = doc + "eat lots of tacos."
     self.doc = doc
     self.query = "tacos burritos enchaladas"
     self.hi = Highlighter(self.doc, self.query)
Ejemplo n.º 19
0
    def load_cursorPos(self, checked):
        print(checked)
        elements = self.data
        check = self.item_data[2]

        index = self.j_tree.currentIndex()
        item = self.model.itemFromIndex(index)
        item_data = QtGui.QStandardItem.data(item)
        self.item_text = QtGui.QStandardItem.text(item)

        for text in elements["Benchmarks"]:
            if item_data[0] == 2:
                for el in text["group_ids"]:
                    if el["id_dupl"] == check:
                        pos = el["position"]
                        start = pos[0]
                        end = pos[1]
                        # length = end - start

                        lineColor = QtGui.QColor(QtCore.Qt.red).lighter(160)
                        Highlighter.highlightText(self.text_doc, start, end,
                                                  lineColor)
Ejemplo n.º 20
0
    def __init__(self, manager, white_player='human', black_player='human'):

        # game state members
        self.game_manager = manager
        self.game_running = False
        self.needs_redraw = True
        self.screen = None
        self.clock = pygame.time.Clock()

        # game components
        self.game_logic = GameLogic(self)
        self.game_grid = GameGrid(self)
        self.game_board = None

        self.white_player = None
        self.black_player = None
        self.initialize_players(white_player, black_player)

        self.turn_manager = TurnManager(self)
        self.highlighter = Highlighter(self)
        self.logger = Logger(self)

        self.buttons = {}
Ejemplo n.º 21
0
        def __init__(self, console, simulation_keywords):
            self.simulation_keywords = simulation_keywords
            self.gui = Gtk.Table()
            self.window = Gtk.ScrolledWindow()
            self.console = console

            self.prevent_button_update = False
            self._textview = Gtk.TextView()

            self._textbuffer = GtkSource.Buffer()
            self._textview.set_buffer(self._textbuffer)

            self._textbuffer.set_max_undo_levels(-1)
            self._textbuffer.set_undo_manager(None)

            self._textbuffer.connect("changed", self.on_text_changed)
            self._textbuffer.connect("paste-done", self.on_text_changed)

            self.error_tag = self._textbuffer.create_tag("error", background="orange")

            font_description = Pango.FontDescription("monospace 9")
            self._textview.modify_font(font_description)

            misc.set_tabs(self._textview, font_description, 4)

            self.window.set_shadow_type(Gtk.ShadowType.IN)
            misc.gtk_set_margin(self.gui, 5, top=10)

            # Init highlight:
            self.highlight = Highlighter(self._textbuffer)
            self.load_highlight()

            self.error_bar = Gtk.InfoBar()
            self.error_bar_label = Gtk.Label()
            self.error_bar.get_content_area().add(self.error_bar_label)
            self.error_bar_label.show()

            self.error_bar.set_message_type(Gtk.MessageType.ERROR)

            self.window.add(self._textview)
            #self.error_bar.set_size_request(80, 100)

            self.gui.attach(self.window, 0, 8, 0, 1)
            self.gui.attach(self.error_bar, 8, 10, 0, 1)

            self.error_bar.set_no_show_all(True)

            # Init script
            self.load_simulation("./simulations/welcome.py")
Ejemplo n.º 22
0
 def register_syntax(self, fileName):
     ext = manage_files.get_file_extension(fileName)[1:]
     if self.highlighter is not None and \
         not self.path.endswith(ext):
         self.highlighter.deleteLater()
     if not self.path.endswith(ext):
         if ext in loader.extensions:
             self.highlighter = Highlighter(
                 self.document(), loader.extensions.get(ext, 'py'))
         else:
             try:
                 self.highlighter = HighlighterPygments(
                     self.document(), fileName)
             except:
                 print 'There is no lexer for this file'
         #for apply rehighlighting (rehighlighting form highlighter not responding)
         self.firstVisibleBlock().document().find('\n').insertText('')
Ejemplo n.º 23
0
    def __init__(self):
        super().__init__()

        self.text_area = TextArea(self, bg="white", fg="black", undo=True)

        self.scrollbar = ttk.Scrollbar(orient="vertical",
                                       command=self.scroll_text)
        self.text_area.configure(yscrollcommand=self.scrollbar.set)

        self.line_numbers = LineNumbers(self,
                                        self.text_area,
                                        bg="grey",
                                        fg="white",
                                        width=1)
        self.highlighter = Highlighter(self.text_area, 'languages/python.yaml')

        self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.line_numbers.pack(side=tk.LEFT, fill=tk.Y)
        self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

        self.bind_events()
Ejemplo n.º 24
0
    def __init__(self, parent):
        super(NoteEditor, self).__init__(parent)
        self.highlighter = Highlighter( self.document() )

        # the language dictionary to be used
        self.dictionary = None
        self.highlighter.setDictionary(self.dictionary)

        # create dictionary selector menu
        self.dictionarySelector = QMenu("&Dictionary")
        self.dictionaryActions = QActionGroup(self)

        self.noDicitionaryAction = self.dictionaryActions.addAction("None")
        self.noDicitionaryAction.setCheckable(True)
        self.dictionarySelector.addAction(self.noDicitionaryAction)

        self.defaultDicitionaryAction = self.dictionaryActions.addAction("Default")
        self.defaultDicitionaryAction.setCheckable(True)
        self.dictionarySelector.addAction(self.defaultDicitionaryAction)

        self.dictionarySelector.addSeparator()

        for lang in enchant.list_languages():
            langAction = self.dictionaryActions.addAction(lang)
            langAction.setCheckable(True)
            self.dictionarySelector.addAction(langAction)

        # connect signal to change language dictionary and set the default language
        self.dictionaryActions.triggered.connect(self.changeDictionary)
        self.defaultDicitionaryAction.trigger()

        # configure the custom context menu for spelling suggestions
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.showContextMenu)

        # settings
        self.noteFilePath = ""                  #stores path to the file being edited
        self.setFont(QFont("Monospace"))
        tabWidth = QFontMetrics( self.currentCharFormat().font() ).width("    ")#get the width of four spaces
        self.setTabStopWidth(tabWidth)                                          #set the default tab width to be that of four spaces
Ejemplo n.º 25
0
    def __init__(self, parent, type):
        super().__init__()

        self._parent = parent
        self._type = type

        fileLabel = QtWidgets.QLabel()
        fileLabel.setText("File:")

        self._fileComboBox = QtWidgets.QComboBox()
        self._fileComboBox.currentIndexChanged.connect(self.currentChanged)

        fileLayout = QtWidgets.QHBoxLayout()
        fileLayout.addWidget(fileLabel)
        fileLayout.addWidget(self._fileComboBox)

        self._editor = ShaderSource()
        self._highlighter = Highlighter(self._editor.document())

        layout = QtWidgets.QVBoxLayout(self)
        layout.addLayout(fileLayout)
        layout.addWidget(self._editor)
Ejemplo n.º 26
0
 def init_ui(self):
     self.text_edit = QTextEdit(self)
     self.setCentralWidget(self.text_edit)
     
     font = QFont("Menlo", 12)
     # TODO: Create a layout and change the line spacing
     #spacing = QFontMetrics(font).lineSpacing()
     self.text_edit.setFont(font)
     self.highlighter = Highlighter(self.text_edit.document(), DEFAULT_RULES, DEFAULT_STYLE)
     #print("Highlighter doc: {}".format(self.text_edit.document()))
     
     menu_bar = self.menuBar()
     m_file = menu_bar.addMenu("File")
     
     i_open = QAction("Open", self)
     i_open.setShortcut('Ctrl+O')
     i_open.triggered.connect(self.on_open)
     
     m_file.addAction(i_open)
     
     self.setGeometry(300, 300, 350, 300)
     self.setWindowTitle("tea")
Ejemplo n.º 27
0
        self.setExtraSelections(extraSelections)


if __name__ == "__main__":

    try:
        import json
    except ImportError:
        import simplejson as json
    from highlighter import Highlighter

    app = QtGui.QApplication(sys.argv)

    js = CodeEditor()
    js.setWindowTitle('javascript')
    hl = Highlighter(js.document(), "javascript")
    js.show()

    def validateJSON():
        style = str(js.toPlainText())
        if not style.strip():  #no point in validating an empty string
            return
        pos = None
        try:
            json.loads(style)
        except ValueError:
            _, e, _ = sys.exc_info()
            s = str(e)
            print(s)
            if s == 'No JSON object could be decoded':
                pos = 0
Ejemplo n.º 28
0
def highlight(text, q, max_length=200, nchars_before=0):
    text = strip_tags(text)
    highlight = Highlighter(q, max_length=max_length)
    return highlight.highlight(text, nchars_before=nchars_before)
Ejemplo n.º 29
0
class EditorBase(QtGui.QPlainTextEdit):
    """ EditorBase

    Base editor class.

    """

    # Todo fix up
    # _indentWidth = aforms.config['editor']['tab_size']
    # _indentUsingSpaces = aforms.config['editor']['ident_using_spaces']
    # _showSpaces = aforms.config['editor']['show_whitespace']

    _indentWidth = 4
    _indentUsingSpaces = True
    _showSpaces = True

    def __init__(self, *args, **kwargs):
        super(EditorBase, self).__init__(*args, **kwargs)

        # Make sure editor always has a monospace font.
        self.__zoom = 0
        self.setFont()

        self.__highlighter = Highlighter(self.document())
        self.__highlighter.setRules(PythonHighlighter)

        # Set general document option
        option = self.document().defaultTextOption()
        option.setFlags(option.flags() | option.IncludeTrailingSpaces |
                        option.AddSpaceForLineAndParagraphSeparators)

        if self.indentUsingSpaces():
            option.setFlags(option.flags() | option.ShowTabsAndSpaces)

        self.document().setDefaultTextOption(option)

        # View Settings
        # self.setShowWhitespace()
        # self.setShowLineEndings()
        # self.setWrap()
        # self.setHighlightCurrentLine()
        # self.setLongLineIndicatorPosition()

        # So that graphical elements wont break.
        self.cursorPositionChanged.connect(self.viewport().update)

    def setZoom(self, zoom):
        size = aforms.config['editor']['font_size']
        self.__zoom = int(max(1-size, zoom))
        self.setFont(self.fontInfo().family())
        return self.__zoom

    def setFont(self, font=None):
        """ Set the font for the editor. """

        defaultFont = aforms.font.defaultFont()

        if font is None:
            font = defaultFont

        try:
            font = QtGui.QFont(font)
        except ValueError:
            font = defaultFont
            print('setFont accepts None, QFont or a string')

        font.setStyleHint(font.TypeWriter, font.PreferDefault)
        fontInfo = QtGui.QFontInfo(font)
        family = fontInfo.family() if fontInfo.fixedPitch() else default.family()
        size = defaultFont.pointSize() + self.__zoom

        font = QtGui.QFont(family, size)
        super(EditorBase, self).setFont(font)
        return font

    def indentUsingSpaces(self):
        return self._indentUsingSpaces

    def indentWidth(self):
        return self._indentWidth

    def setIndentWidth(self, value):
        value = int(value)
        if value <= 0:
            raise ValueError('indentWidth must be greater than 0.')
        self._indentWidth = value
        self.setTabStopWidth(self.fontMetric().widtrh('i'*self._indentWidth))

    def indentBlock(self, cursor, amount=1):
        pass
Ejemplo n.º 30
0
 def __init__(self):
     super().__init__()
     self.ui = Ui_MainWindow()
     self.init_UI()  # 界面绘制交给InitUi方法
     self.file_status = FileStatus()
     self.highlighter = Highlighter(self.ui)
Ejemplo n.º 31
0
class TextEditor(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.init_UI()  # 界面绘制交给InitUi方法
        self.file_status = FileStatus()
        self.highlighter = Highlighter(self.ui)

    def init_UI(self):
        self.ui.setupUi(self)
        self.ui.textEdit.setFontPointSize(12)
        self.ui.textEdit.setStyleSheet("background-color:#F5F5F5")
        self.ui.textBrowser.setStyleSheet("background-color:#F5F5F5")
        self.setWindowTitle('未命名')
        self.show()

    @pyqtSlot()
    def on_textEdit_textChanged(self):
        if self.highlighter.flag_format_changed:
            self.highlighter.flag_format_changed = False
            return

        self.file_status.set_TextChanged()

        # set windows name
        if not (self.file_status.is_saved
                or self.file_status.is_saveFlag_setted):
            self.setWindowTitle(self.file_status.filename + '*')
            self.file_status.is_saveFlag_setted = True

        # set font
        if self.file_status.is_openFile:
            self.highlighter.mode_openfile()
            self.file_status.is_openFile = False
        else:
            self.highlighter.mode_normal()

    @pyqtSlot()
    # 打开文件
    def on_act_open_triggered(self):
        filename = QFileDialog.getOpenFileName(
            self,
            caption='Open File',
            directory='./',
            filter="c files(*.c);; cpp files(*.cpp)")
        if filename[0] == '':
            return
        with open(filename[0], 'r', encoding='UTF-8') as f:
            content = ''
            for li in f.readlines():
                content += li
        # file_status
        self.file_status.set_openStatus(filename[0])
        # windows title
        self.setWindowTitle(self.file_status.filename)
        # set_text
        self.ui.textEdit.setText(content)

    @pyqtSlot()
    # 另存为
    def on_act_saveAs_triggered(self):
        filename = QFileDialog.getSaveFileName(
            self,
            caption='Open File',
            directory='./',
            filter="c files(*.c);; cpp files(*.cpp)")
        if filename[0] == '':
            return
        with open(filename[0], 'w', encoding='UTF-8') as f:
            f.write(self.ui.textEdit.document().toPlainText())
        self.setWindowTitle(self.file_status.filename)
        self.file_status.set_saveStatus()

    @pyqtSlot()
    # 保存文件
    def on_act_save_triggered(self):
        if self.file_status.is_untitle:
            self.on_act_saveAs_triggered()
        else:
            with open(self.file_status.filedir, 'w', encoding='UTF-8') as f:
                f.write(self.ui.textEdit.document().toPlainText())
                # windows title
                self.setWindowTitle(self.file_status.filename)
                self.file_status.set_saveStatus()

    @pyqtSlot()
    # 新建
    def on_act_new_triggered(self):
        self.ui.textEdit.setText('')
        self.setWindowTitle('未命名')
        self.file_status.__init__()

    @pyqtSlot()
    # 剪切
    def on_act_undo_triggered(self):
        self.ui.textEdit.undo()

    @pyqtSlot()
    # 剪切
    def on_act_cut_triggered(self):
        self.ui.textEdit.cut()

    @pyqtSlot()
    # 复制
    def on_act_copy_triggered(self):
        self.ui.textEdit.copy()

    @pyqtSlot()
    # 粘贴
    def on_act_paste_triggered(self):
        self.ui.textEdit.paste()
Ejemplo n.º 32
0
class NoteEditor(QPlainTextEdit):
    """The note editing class used uses a plain text editing window to edit markdown files (notes)."""

    def __init__(self, parent):
        super(NoteEditor, self).__init__(parent)
        self.highlighter = Highlighter( self.document() )

        # the language dictionary to be used
        self.dictionary = None
        self.highlighter.setDictionary(self.dictionary)

        # create dictionary selector menu
        self.dictionarySelector = QMenu("&Dictionary")
        self.dictionaryActions = QActionGroup(self)

        self.noDicitionaryAction = self.dictionaryActions.addAction("None")
        self.noDicitionaryAction.setCheckable(True)
        self.dictionarySelector.addAction(self.noDicitionaryAction)

        self.defaultDicitionaryAction = self.dictionaryActions.addAction("Default")
        self.defaultDicitionaryAction.setCheckable(True)
        self.dictionarySelector.addAction(self.defaultDicitionaryAction)

        self.dictionarySelector.addSeparator()

        for lang in enchant.list_languages():
            langAction = self.dictionaryActions.addAction(lang)
            langAction.setCheckable(True)
            self.dictionarySelector.addAction(langAction)

        # connect signal to change language dictionary and set the default language
        self.dictionaryActions.triggered.connect(self.changeDictionary)
        self.defaultDicitionaryAction.trigger()

        # configure the custom context menu for spelling suggestions
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.showContextMenu)

        # settings
        self.noteFilePath = ""                  #stores path to the file being edited
        self.setFont(QFont("Monospace"))
        tabWidth = QFontMetrics( self.currentCharFormat().font() ).width("    ")#get the width of four spaces
        self.setTabStopWidth(tabWidth)                                          #set the default tab width to be that of four spaces

    #%%% To do: use 'keyPressEvent' to implement auto-indent %%%


    def setWrapMode(self, wrapMode):
        self.setWordWrapMode(wrapMode)


    def getDictionarySelector(self):
        return self.dictionarySelector


    def changeDictionary(self, action):
        """Change the spell check dictionary (language) based on the languaged selected from the 'Dictionary' menu."""

        # change the language dictionary
        if action is self.noDicitionaryAction:
            self.dictionary = None
        elif action is self.defaultDicitionaryAction:
            self.dictionary = enchant.Dict(locale.getdefaultlocale()[0])
        else:
            self.dictionary = enchant.Dict(action.text())

        # rehighlight the text to find spelling errors
        self.highlighter.setDictionary(self.dictionary)
        self.highlighter.rehighlight()


    def showContextMenu(self, position):
        """Shows an appropriate context menu for the area of the editor that was right-clicked."""

        # create the context menu that will be displayed
        contextMenu = QMenu()

        # select the word that was right-clicked
        textCursor = self.cursorForPosition(position)
        textCursor.select(QTextCursor.WordUnderCursor)
        word = textCursor.selectedText()

        # if a word was selected and it's misspelled, show a suggestion menu
        if word and not len(word) is 0:
            if not self.dictionary.check(word):

                # create the suggestion menu
                for suggestion in self.dictionary.suggest(word):
                    a = contextMenu.addAction(suggestion)
                    a.setData("custom")

                contextMenu.addSeparator()
                a = contextMenu.addAction("Add to dictionary")
                a.setData("custom")
            else:
                a = contextMenu.addAction("Remove from dictionary")
                a.setData("custom")

            contextMenu.addSeparator()

        # add standard context menu actions
        standardMenu = self.createStandardContextMenu(position);
        isFirst = True
        for a in standardMenu.children():
            if isFirst:
                isFirst = False
            else:
                contextMenu.addAction(a)

        # show context menu
        action = contextMenu.exec(self.mapToGlobal(position))

        # if a suggestion was selected, replace the current word with it
        if action and action.data() == "custom":
            if action.text() == "Add to dictionary":
                self.dictionary.add(word)
            elif action.text() == "Remove from dictionary":
                self.dictionary.remove(word)
            else:
                textCursor.removeSelectedText()
                textCursor.insertText(action.text())


    def openFileRequest(self, filePath):
        """Open a file using its path (string) in the editor.  Return 'True' if successful, 'False' otherwise."""

        noErrors = True                 #set return state
        noteFile = open(filePath, "r")
        if noteFile:                    #if the file was opened successfully
            self.setPlainText( noteFile.read() )    #set its contents in the editor
            self.noteFilePath = filePath            #save the file path to the internal variable
            self.noteFileChanged.emit( os.path.abspath(self.noteFilePath) ) #emit signal to notify other objects of file change
        else:                           #else, return an error
            noErrors = False

        noteFile.close()
        return noErrors


    def writeToFile(self, filePath):
        """Writes text in editor to file 'filePath'.  Return 'True' if successful, 'False' otherwise."""

        noErrors = True
        if os.path.exists(filePath):    #check if file exists
            filePath = os.path.abspath(filePath)    #make path absolute just in case...
            noteFile = open(filePath, "w")
            if noteFile:                            #if file was opened successfully
                noteFile.write( self.toPlainText() )    #write text to file
            else:
                noErrors = False
        else:
            noErrors = False

        return noErrors


    def saveFileRequest(self):
        """Saves text in editor to note file.  Return 'True' if successful, 'False' otherwise."""

        noErrors = True
        if self.noteFilePath != "":                     #if note path is set (the editor knows which file it should save to)
            noErrors = self.writeToFile( self.noteFilePath )#write text to note file
        else:
            noErrors = False

        return noErrors


    def saveAsRequested(self, filePath):
        """Save text in editor to a new file ('filePath') and set it as the new note file.  Return 'True' if successful, 'False' otherwise."""

        noErrors = True

        newFile = open(filePath, "w+")          #create the new file
        newFile.close()

        noErrors = self.writeToFile( filePath ) #write text to the new file
        if noErrors:                            #if no errors occured
            self.noteFilePath = filePath            #set the new file as the internal note file
            self.noteFileChanged.emit( os.path.abspath(self.noteFilePath) ) #emit signal to notify other objects of file change

        return noErrors


    def saveCopyAsRequested(self, filePath):
        """Save note to a new file without loading it.  Return 'True' if successful, 'False' otherwise."""

        noErrors = True

        newFile = open(filePath, "w+")          #create the new file
        newFile.close()

        noErrors = self.writeToFile( filePath ) #wrtie text to the new file

        ########################################################################################
        ### Note that 'self.noteFilePath' (path to the note file being edited) is not changed ##
        ########################################################################################

        return noErrors


    def getNoteFileName(self):
        """Returns the file name of the note being edited."""

        return os.path.basename(self.noteFilePath)


    def getNotePath(self):
        """Returns the path to the note being edited."""

        return self.noteFilePath


    #~signals~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    noteFileChanged = pyqtSignal([str]) #a signal to be emitted when 'self.noteFilePath' (path to the note file being edited) is changed
Ejemplo n.º 33
0
class Main(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)

        self.doctree=None
        self.lineMarks={}

        # We put things we want rendered here
        self.render_queue = Queue()
        # We get things rendered back
        self.pdf_queue = Queue()
        # We get doctrees for the outline viewer
        self.doctree_queue = Queue()

        print('Starting background renderer...', end=' ')
        self.renderProcess=Process(target = renderQueue,
            args=(self.render_queue, self.pdf_queue, self.doctree_queue))
        self.renderProcess.daemon=True
        self.renderProcess.start()
        print('DONE')

        # This is always the same
        self.ui=Ui_MainWindow()
        self.ui.setupUi(self)

        # Adjust column widths in the structure tree
        self.ui.tree.header().setStretchLastSection(False)
        self.ui.tree.header().setResizeMode(0, QtGui.QHeaderView.Stretch)
        self.ui.tree.header().setResizeMode(1, QtGui.QHeaderView.ResizeToContents)

        self.pdf=PDFWidget()

        self.ui.pageNum = QtGui.QSpinBox()
        self.ui.pageNum.setMinimum(1)
        self.ui.pageNum.setValue(1)
        self.connect(self.pdf,QtCore.SIGNAL('pageCount'),
            self.ui.pageNum.setMaximum)
        self.connect(self.pdf,QtCore.SIGNAL('pageChanged'),
            self.ui.pageNum.setValue)
        self.connect(self.ui.pageNum,QtCore.SIGNAL('valueChanged(int)'),
            self.pdf.gotoPage)

        self.ui.actionShow_ToolBar=self.ui.toolBar.toggleViewAction()
        self.ui.actionShow_ToolBar.setText("Show Main Toolbar")
        self.ui.menuView.addAction(self.ui.actionShow_ToolBar)

        self.ui.pdfbar.addAction(self.pdf.ui.previous)
        self.ui.pdfbar.addWidget(self.ui.pageNum)
        self.ui.pdfbar.addAction(self.pdf.ui.__next__)
        self.ui.pdfbar.addSeparator()
        self.ui.pdfbar.addAction(self.pdf.ui.zoomin)
        self.ui.pdfbar.addAction(self.pdf.ui.zoomout)
        self.ui.actionShow_PDFBar=self.ui.pdfbar.toggleViewAction()
        self.ui.actionShow_PDFBar.setText("Show PDF Toolbar")
        self.ui.menuView.addAction(self.ui.actionShow_PDFBar)

        self.ui.dockLayout.addWidget(self.ui.pdfbar)
        self.ui.dockLayout.addWidget(self.pdf)
        self.ui.dock.hide()
        self.ui.actionShow_PDF=self.ui.dock.toggleViewAction()
        self.ui.actionShow_PDF.setText('Show Preview')
        self.ui.menuView.addAction(self.ui.actionShow_PDF)
        self.ui.actionShow_Structure=self.ui.structure.toggleViewAction()
        self.ui.actionShow_Structure.setText('Show Document Outline')
        self.ui.menuView.addAction(self.ui.actionShow_Structure)

        self.text_md5=''
        self.style_md5=''

        self.hl1 = Highlighter(self.ui.text.document(),'rest')
        self.hl2 = Highlighter(self.ui.style.document(),'javascript')

        self.editorPos=QtGui.QLabel()
        self.ui.statusBar.addWidget(self.editorPos)
        self.editorPos.show()

        self.statusMessage=QtGui.QLabel()
        self.ui.statusBar.addWidget(self.statusMessage)
        self.statusMessage.show()

        self.on_text_cursorPositionChanged()
        self.on_actionRender_triggered()

        # Connect editing actions to the editors
        self.ui.text.undoAvailable.connect(self.ui.actionUndo1.setEnabled)
        self.ui.actionUndo1.triggered.connect(self.ui.text.undo)
        self.ui.text.redoAvailable.connect(self.ui.actionRedo1.setEnabled)
        self.ui.actionRedo1.triggered.connect(self.ui.text.redo)

        self.ui.text.copyAvailable.connect(self.ui.actionCopy1.setEnabled)
        self.ui.actionCopy1.triggered.connect(self.ui.text.copy)
        self.ui.text.copyAvailable.connect(self.ui.actionCut1.setEnabled)
        self.ui.actionCut1.triggered.connect(self.ui.text.cut)
        self.ui.actionPaste1.triggered.connect(self.ui.text.paste)


        self.ui.style.undoAvailable.connect(self.ui.actionUndo2.setEnabled)
        self.ui.actionUndo2.triggered.connect(self.ui.style.undo)
        self.ui.style.redoAvailable.connect(self.ui.actionRedo2.setEnabled)
        self.ui.actionRedo2.triggered.connect(self.ui.style.redo)

        self.ui.style.copyAvailable.connect(self.ui.actionCopy2.setEnabled)
        self.ui.actionCopy2.triggered.connect(self.ui.style.copy)
        self.ui.style.copyAvailable.connect(self.ui.actionCut2.setEnabled)
        self.ui.actionCut2.triggered.connect(self.ui.style.cut)
        self.ui.actionPaste2.triggered.connect(self.ui.style.paste)

        self.clipBoard=QtGui.QApplication.clipboard()
        self.clipBoard.changed.connect(self.clipChanged)

        self.hookEditToolbar(self.ui.text)
        self.clipChanged(QtGui.QClipboard.Clipboard)

        self.text_fname=None
        self.style_fname=None
        self.pdf_fname=None

        self.ui.searchbar.setVisible(False)
        self.ui.searchWidget=SearchWidget()
        self.ui.searchbar.addWidget(self.ui.searchWidget)
        self.ui.actionFind.triggered.connect(self.ui.searchbar.show)
        self.ui.actionFind.triggered.connect(self.ui.searchWidget.ui.text.setFocus)
        self.ui.searchWidget.ui.close.clicked.connect(self.ui.searchbar.hide)
        self.ui.searchWidget.ui.close.clicked.connect(self.returnFocus)
        self.ui.searchWidget.ui.next.clicked.connect(self.doFind)
        self.ui.searchWidget.ui.previous.clicked.connect(self.doFindBackwards)

        self.updatePdf()

        self.renderTimer=QtCore.QTimer()
        self.renderTimer.timeout.connect(self.on_actionRender_triggered)
        self.renderTimer.start(5000)

    def returnFocus(self):
        """after the search bar closes, focus on the editing widget"""
        print('RF:', self.ui.tabs.currentIndex())
        if self.ui.tabs.currentIndex()==0:
            self.ui.text.setFocus()
        else:
            self.ui.style.setFocus()

    def doFindBackwards (self):
        return self.doFind(backwards=True)

    def doFind(self, backwards=False):

        flags=QtGui.QTextDocument.FindFlags()
        print(flags)
        if backwards:
            flags=QtGui.QTextDocument.FindBackward
        if self.ui.searchWidget.ui.matchCase.isChecked():
            flags=flags|QtGui.QTextDocument.FindCaseSensitively

        text=str(self.ui.searchWidget.ui.text.text())

        print('Serching for:',text)

        if self.ui.tabs.currentIndex()==0:
            r=self.ui.text.find(text,flags)
        else:
            r=self.ui.style.find(text,flags)
        if r:
            self.statusMessage.setText('')
        else:
            self.statusMessage.setText('%s not found'%text)

    def clipChanged(self, mode=None):
        if mode is None: return
        if mode == QtGui.QClipboard.Clipboard:
            if str(self.clipBoard.text()):
                self.ui.actionPaste1.setEnabled(True)
                self.ui.actionPaste2.setEnabled(True)
            else:
                self.ui.actionPaste1.setEnabled(False)
                self.ui.actionPaste2.setEnabled(False)

    def hookEditToolbar(self, editor):
        if editor == self.ui.text:
            self.ui.actionUndo2.setVisible(False)
            self.ui.actionRedo2.setVisible(False)
            self.ui.actionCut2.setVisible(False)
            self.ui.actionPaste2.setVisible(False)
            self.ui.actionCopy2.setVisible(False)
            self.ui.actionUndo1.setVisible(True)
            self.ui.actionRedo1.setVisible(True)
            self.ui.actionCut1.setVisible(True)
            self.ui.actionPaste1.setVisible(True)
            self.ui.actionCopy1.setVisible(True)
        else:
            self.ui.actionUndo1.setVisible(False)
            self.ui.actionRedo1.setVisible(False)
            self.ui.actionCut1.setVisible(False)
            self.ui.actionPaste1.setVisible(False)
            self.ui.actionCopy1.setVisible(False)
            self.ui.actionUndo2.setVisible(True)
            self.ui.actionRedo2.setVisible(True)
            self.ui.actionCut2.setVisible(True)
            self.ui.actionPaste2.setVisible(True)
            self.ui.actionCopy2.setVisible(True)


    def createPopupMenu(self):
        self.popup=QtGui.QMenu()
        self.popup.addAction(self.ui.actionShow_ToolBar)
        self.popup.addAction(self.ui.actionShow_PDFBar)
        self.popup.addAction(self.ui.actionShow_PDF)
        return self.popup

    def enableHL(self):
        self.hl1.enabled=True
        self.hl2.enabled=True
        self.hl1.rehighlight()
        self.hl2.rehighlight()

    def disableHL(self):
        self.hl1.enabled=False
        self.hl2.enabled=False

    def on_actionSettings_triggered(self, b=None):
        if b is not None: return

        # I need to create a stylesheet object so I can parse and merge
        # the current stylesheet

        try:
            data=json.loads(str(self.ui.style.toPlainText()))
        except: # TODO: fail if sheet doesn't validate
            data={}
        config=ConfigDialog(data=copy(data))
        config.exec_()

        # merge the edited stylesheet with current one because the editor
        # is not complete yet. When it is, just replace it.
        data.update(config.data)
        self.ui.style.setPlainText(json.dumps(data, indent=2))

    def on_actionTest_Action_triggered(self, b=None):
        if b is not None: return



        self.testwidget=PageTemplates(self.styles)
        self.testwidget.show()


    def on_tree_itemClicked(self, item=None, column=None):
        if item is None: return

        destline=int(item.text(1))-1
        destblock=self.ui.text.document().findBlockByLineNumber(destline)
        cursor=self.ui.text.textCursor()
        cursor.setPosition(destblock.position())
        self.ui.text.setTextCursor(cursor)
        self.ui.text.ensureCursorVisible()

    def on_actionAbout_Bookrest_triggered(self, b=None):
        if b is None: return
        dlg=AboutDialog()
        dlg.exec_()

    def on_actionSave_Text_triggered(self, b=None):
        if b is not None: return

        if self.text_fname is not None:
            f=codecs.open(self.text_fname,'w+','utf-8')
            f.seek(0)
            f.write(str(self.ui.text.toPlainText()))
            f.close()
        else:
            self.on_actionSaveAs_Text_triggered()


    def on_actionSaveAs_Text_triggered(self, b=None):
        if b is not None: return

        fname=str(QtGui.QFileDialog.getSaveFileName(self,
                            'Save As',
                            os.getcwd(),
                            'reSt files (*.txt *.rst)'
                            ))
        if fname:
            self.text_fname=fname
            self.on_actionSave_Text_triggered()

    def on_actionLoad_Text_triggered(self, b=None):
        if b is None: return
        fname=QtGui.QFileDialog.getOpenFileName(self,
                                                'Open File',
                                                os.getcwd(),
                                                'reSt files (*.txt *.rst)'
                                                )
        self.text_fname=fname
        self.disableHL()
        self.ui.text.setPlainText(codecs.open(self.text_fname,'r','utf-8').read())
        self.enableHL()

    def on_actionSave_Style_triggered(self, b=None):
        if b is not None: return

        if self.style_fname is not None:
            f=codecs.open(self.style_fname,'w+','utf-8')
            f.seek(0)
            f.write(str(self.ui.style.toPlainText()))
            f.close()
        else:
            self.on_actionSaveAs_Style_triggered()


    def on_actionSaveAs_Style_triggered(self, b=None):
        if b is not None: return

        fname=str(QtGui.QFileDialog.getSaveFileName(self,
                            'Save As',
                            os.getcwd(),
                            'style files (*.json *.style)'
                            ))
        if fname:
            self.style_fname=fname
            self.on_actionSave_Style_triggered()


    def on_actionLoad_Style_triggered(self, b=None):
        if b is None: return

        fname=QtGui.QFileDialog.getOpenFileName(self,
                                                'Open File',
                                                os.getcwd(),
                                                'style files (*.json *.style)'
                                                )
        self.style_fname=fname
        self.disableHL()
        self.ui.style.setPlainText(codecs.open(self.style_fname,'rb', 'utf-8').read())
        self.enableHL()

    def on_actionSave_PDF_triggered(self, b=None):
        if b is not None: return

        # render it without line numbers in the toc
        self.on_actionRender_triggered(preview=False)

        if self.pdf_fname is not None:
            f=open(self.pdf_fname,'wb+')
            f.seek(0)
            f.write(self.goodPDF)
            f.close()
        else:
            self.on_actionSaveAs_PDF_triggered()


    def on_actionSaveAs_PDF_triggered(self, b=None):
        if b is not None: return

        fname=str(QtGui.QFileDialog.getSaveFileName(self,
                            'Save As',
                            os.getcwd(),
                            'PDF files (*.pdf)'
                            ))
        if fname:
            self.pdf_fname=fname
            self.on_actionSave_PDF_triggered()

    def on_tabs_currentChanged(self, i=None):
        print('IDX:',self.ui.tabs.currentIndex())
        if self.ui.tabs.currentIndex() == 0:
            self.on_text_cursorPositionChanged()
            print('hooking text editor')
            self.hookEditToolbar(self.ui.text)
        else:
            self.on_style_cursorPositionChanged()
            print('hooking style editor')
            self.hookEditToolbar(self.ui.style)

    def on_style_cursorPositionChanged(self):
        cursor=self.ui.style.textCursor()
        self.editorPos.setText('Line: %d Col: %d'%(cursor.blockNumber(),cursor.columnNumber()))

    def on_text_cursorPositionChanged(self):
        cursor=self.ui.text.textCursor()
        row=cursor.blockNumber()
        column=cursor.columnNumber()
        self.editorPos.setText('Line: %d Col: %d'%(row,column))
        l='line-%s'%(row+1)
        m=self.lineMarks.get(l,None)
        if m:
            self.pdf.gotoPosition(*m)
    def validateStyle(self):
        style=str(self.ui.style.toPlainText())
        if not style.strip(): #no point in validating an empty string
            self.statusMessage.setText('')
            return
        pos=None
        try:
            json.loads(style)
            self.statusMessage.setText('')
        except ValueError as e:
            s=str(e)
            if s == 'No JSON object could be decoded':
                pos=0
            elif s.startswith('Expecting '):
                pos=int(s.split(' ')[-1][:-1])
            elif s.startswith('Extra data'):
                pos=int(s.split(' ')[-3])
            else:
                pass
            self.statusMessage.setText('Stylesheet error: %s'%s)

        # This makes a red bar appear in the line
        # containing position pos
        self.ui.style.highlightError(pos)

    on_style_textChanged = validateStyle

    def on_actionRender_triggered(self, b=None, preview=True):
        if b is not None: return
        text=str(self.ui.text.toPlainText())
        style=str(self.ui.style.toPlainText())
        self.hl1.rehighlight()
        m1=md5()
        m1.update(text.encode('utf-8'))
        m1=m1.digest()
        m2=md5()
        m2.update(style.encode('utf-8'))
        m2=m2.digest()

        flag = m1 != self.text_md5
        style_file=None
        if m2 != self.style_md5 and style:
            fd, style_file=tempfile.mkstemp()
            os.write(fd,style)
            os.close(fd)
            print('Loading styles from style_file')
            flag = True
        if flag:
            if not preview:
                pass
                # Send text to the renderer in foreground
                # FIXME: render is no longer accessible from the parent
                # process
                #doctree = docutils.core.publish_doctree(text)
                #self.goodPDF=render(doctree, preview=False)
            else:
                # Que to render in background
                self.render_queue.put([style_file, text, preview])
                self.text_md5=m1
                self.style_md5=m2

    def updatePdf(self):

        # See if there is something in the doctree Queue
        try:
            self.doctree, self.warnings = self.doctree_queue.get(False)
            self.doctree.reporter=log
            class Visitor(docutils.nodes.SparseNodeVisitor):

                def __init__(self, document, treeWidget):
                    self.treeWidget=treeWidget
                    self.treeWidget.clear()
                    self.doctree=document
                    self.nodeDict={}
                    docutils.nodes.SparseNodeVisitor.__init__(self, document)

                def visit_section(self, node):
                    print('SECTION:',node.line, end=' ')
                    item=QtGui.QTreeWidgetItem(["",str(node.line)])
                    if node.parent==self.doctree:
                        # Top level section
                        self.treeWidget.addTopLevelItem(item)
                        self.nodeDict[id(node)]=item
                    else:
                        self.nodeDict[id(node.parent)].addChild(item)
                        self.nodeDict[id(node)]=item

                def visit_title(self, node):
                    if id(node.parent) in self.nodeDict:
                        self.nodeDict[id(node.parent)].setText(0,node.astext())

                def visit_document(self,node):
                    print('DOC:',node.line)

            print(self.doctree.__class__)
            self.visitor=Visitor(self.doctree, self.ui.tree)
            self.doctree.walkabout(self.visitor)
            print(self.visitor.nodeDict)

        except Empty:
            pass

        # See if there is something in the PDF Queue
        try:
            self.lastPDF=self.pdf_queue.get(False)
            self.pdf.loadDocument(self.lastPDF)
            toc=self.pdf.document.toc()
            if toc:
                tempMarks=[]
                def traverse(node):
                    children=node.childNodes()
                    for i in range(children.length()):
                        n=children.item(i)
                        e=n.toElement()
                        if e:
                            tag=str(e.tagName())
                            if tag.startswith('LINE'):
                                dest=str(e.attribute('Destination'))
                                dest=QtPoppler.Poppler.LinkDestination(dest)
                                tempMarks.append([int(tag.split('-')[1]),
                                    [dest.pageNumber(), dest.top(), dest.left(),1.]])
                        traverse(n)
                traverse(toc)
                tempMarks.sort()

                self.lineMarks={}
                lastMark=None
                lastKey=0
                for key,dest in tempMarks:
                    # Fix height of the previous mark, unless we changed pages
                    if lastMark and self.lineMarks[lastMark][0]==dest[0]:
                        self.lineMarks[lastMark][3]=dest[1]
                    # Fill missing lines

                    if lastMark:
                        ldest=self.lineMarks[lastMark]
                    else:
                        ldest=[1,0,0,0]
                    for n in range(lastKey,key):
                        self.lineMarks['line-%s'%n]=ldest
                    k='line-%s'%key
                    self.lineMarks[k]=dest
                    lastMark = k
                    lastKey = key

            self.on_text_cursorPositionChanged()
        except Empty: #Nothing there
            pass

        # Schedule to run again
        QtCore.QTimer.singleShot(500,self.updatePdf)
Ejemplo n.º 34
0
    def __init__(self):
        super().__init__()

        self.title('Python Text Editor v3')
        self.geometry('800x600')

        self.foreground = 'black'
        self.background = 'lightgrey'
        self.text_foreground = '#313131'
        self.text_background = '#f0f0f0'
        self.terminal_background = 'darkcyan'
        self.terminal_foreground = 'white'

        self.config_dir = os.path.join(str(Path.home()), '.tkedit')

        self.default_scheme_path = os.path.join(self.config_dir,
                                                'schemes/default.yaml')
        self.python_language_path = os.path.join(self.config_dir,
                                                 'languages/python.yaml')
        self.font_scheme_path = os.path.join(self.config_dir,
                                             'schemes/font.yaml')
        self.create_config_directory_if_needed()

        self.load_scheme_file(self.default_scheme_path)
        self.configure_ttk_elements()

        # Change
        self.font_size = 14
        self.font_family = "Droid Sana Mono"

        self.terminal_font_size = 12
        self.terminal_font_family = "Consolas"
        # Change

        self.load_font_file(self.font_scheme_path)

        self.text_area = TextArea(self,
                                  bg=self.text_background,
                                  fg=self.text_foreground,
                                  undo=True,
                                  font=(self.font_family, self.font_size))

        self.scrollbar = ttk.Scrollbar(orient="vertical",
                                       command=self.scroll_text)
        self.text_area.configure(yscrollcommand=self.scrollbar.set)

        self.line_numbers = LineNumbers(self,
                                        self.text_area,
                                        bg="grey",
                                        fg="white",
                                        width=1,
                                        font=(self.font_family,
                                              self.font_size))
        self.highlighter = Highlighter(self.text_area,
                                       self.python_language_path)
        self.terminal = Terminal(self,
                                 height=8,
                                 bg=self.terminal_background,
                                 fg=self.terminal_foreground,
                                 undo=True,
                                 font=(self.terminal_font_family,
                                       self.terminal_font_size))

        self.menu = tk.Menu(self, bg=self.background, fg=self.foreground)
        self.all_menus = [self.menu]

        self.text_area.__setattr__("update_line",
                                   self.line_numbers.force_update)
        self.text_area.__setattr__("update_highlight",
                                   self.highlighter.force_highlight)

        sub_menu_items = ["file", "edit", "tools", "help"]
        self.generate_sub_menus(sub_menu_items)
        self.configure(menu=self.menu)

        self.right_click_menu = tk.Menu(self,
                                        bg=self.background,
                                        fg=self.foreground,
                                        tearoff=0)
        self.right_click_menu.add_command(label='Cut', command=self.edit_cut)
        self.right_click_menu.add_command(label='Copy', command=self.edit_copy)
        self.right_click_menu.add_command(label='Paste',
                                          command=self.edit_paste)
        # Change
        self.right_click_menu.add_command(label='Undo', command=self.edit_undo)
        self.right_click_menu.add_command(label='Redo', command=self.edit_redo)
        # Change
        self.all_menus.append(self.right_click_menu)

        # change
        self.count_area = tk.Text(self, height=1)
        self.count_area.pack(side=tk.BOTTOM, fill=tk.X)
        # change
        # Change
        self.terminal.pack(side=tk.BOTTOM, fill=tk.X)
        # Change
        self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.line_numbers.pack(side=tk.LEFT, fill=tk.Y)
        self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

        self.bind_events()

        self.open_file = ''
Ejemplo n.º 35
0
class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title('Python Text Editor v3')
        self.geometry('800x600')

        self.foreground = 'black'
        self.background = 'lightgrey'
        self.text_foreground = '#313131'
        self.text_background = '#f0f0f0'
        self.terminal_background = 'darkcyan'
        self.terminal_foreground = 'white'

        self.config_dir = os.path.join(str(Path.home()), '.tkedit')

        self.default_scheme_path = os.path.join(self.config_dir,
                                                'schemes/default.yaml')
        self.python_language_path = os.path.join(self.config_dir,
                                                 'languages/python.yaml')
        self.font_scheme_path = os.path.join(self.config_dir,
                                             'schemes/font.yaml')
        self.create_config_directory_if_needed()

        self.load_scheme_file(self.default_scheme_path)
        self.configure_ttk_elements()

        # Change
        self.font_size = 14
        self.font_family = "Droid Sana Mono"

        self.terminal_font_size = 12
        self.terminal_font_family = "Consolas"
        # Change

        self.load_font_file(self.font_scheme_path)

        self.text_area = TextArea(self,
                                  bg=self.text_background,
                                  fg=self.text_foreground,
                                  undo=True,
                                  font=(self.font_family, self.font_size))

        self.scrollbar = ttk.Scrollbar(orient="vertical",
                                       command=self.scroll_text)
        self.text_area.configure(yscrollcommand=self.scrollbar.set)

        self.line_numbers = LineNumbers(self,
                                        self.text_area,
                                        bg="grey",
                                        fg="white",
                                        width=1,
                                        font=(self.font_family,
                                              self.font_size))
        self.highlighter = Highlighter(self.text_area,
                                       self.python_language_path)
        self.terminal = Terminal(self,
                                 height=8,
                                 bg=self.terminal_background,
                                 fg=self.terminal_foreground,
                                 undo=True,
                                 font=(self.terminal_font_family,
                                       self.terminal_font_size))

        self.menu = tk.Menu(self, bg=self.background, fg=self.foreground)
        self.all_menus = [self.menu]

        self.text_area.__setattr__("update_line",
                                   self.line_numbers.force_update)
        self.text_area.__setattr__("update_highlight",
                                   self.highlighter.force_highlight)

        sub_menu_items = ["file", "edit", "tools", "help"]
        self.generate_sub_menus(sub_menu_items)
        self.configure(menu=self.menu)

        self.right_click_menu = tk.Menu(self,
                                        bg=self.background,
                                        fg=self.foreground,
                                        tearoff=0)
        self.right_click_menu.add_command(label='Cut', command=self.edit_cut)
        self.right_click_menu.add_command(label='Copy', command=self.edit_copy)
        self.right_click_menu.add_command(label='Paste',
                                          command=self.edit_paste)
        # Change
        self.right_click_menu.add_command(label='Undo', command=self.edit_undo)
        self.right_click_menu.add_command(label='Redo', command=self.edit_redo)
        # Change
        self.all_menus.append(self.right_click_menu)

        # change
        self.count_area = tk.Text(self, height=1)
        self.count_area.pack(side=tk.BOTTOM, fill=tk.X)
        # change
        # Change
        self.terminal.pack(side=tk.BOTTOM, fill=tk.X)
        # Change
        self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.line_numbers.pack(side=tk.LEFT, fill=tk.Y)
        self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

        self.bind_events()

        self.open_file = ''

    def bind_events(self):
        self.text_area.bind("<MouseWheel>", self.scroll_text)
        self.text_area.bind("<Button-4>", self.scroll_text)
        self.text_area.bind("<Button-5>", self.scroll_text)
        self.text_area.bind("<Button-3>", self.show_right_click_menu)
        # Change
        self.count_area.bind(self.count_text())
        # Change

        self.bind('<Control-f>', self.show_find_window)

        self.bind('<Control-n>', self.file_new)
        self.bind('<Control-o>', self.file_open)
        self.bind('<Control-s>', self.file_save)

        self.bind('<Control-h>', self.help_about)

        self.bind('<Control-m>', self.tools_change_syntax_highlighting)
        self.bind('<Control-g>', self.tools_change_colour_scheme)
        self.bind('<Control-l>', self.tools_change_font)

        self.line_numbers.bind("<MouseWheel>", lambda e: "break")
        self.line_numbers.bind("<Button-4>", lambda e: "break")
        self.line_numbers.bind("<Button-5>", lambda e: "break")

    # change
    def count_text(self):
        contents = self.text_area.get(1.0, tk.END).replace(" ", "").split("\n")
        self.count_area.delete(1.0, tk.END)
        self.count_area.insert(
            tk.END,
            "当前字数为:" + str(CountWord(contents).bind_event(contents)) + " 字")
        return self.after(50, self.count_text)

    # change

    def scroll_text(self, *args):
        if len(args) > 1:
            self.text_area.yview_moveto(args[1])
            self.line_numbers.yview_moveto(args[1])
        else:
            event = args[0]
            if event.delta:
                move = -1 * (event.delta / 120)
            else:
                if event.num == 5:
                    move = 1
                else:
                    move = -1

            self.text_area.yview_scroll(int(move), "units")
            self.line_numbers.yview_scroll(int(move) * 3, "units")

    def show_find_window(self, event=None):
        FindWindow(self.text_area)

    def show_right_click_menu(self, event):
        x = self.winfo_x() + self.text_area.winfo_x() + event.x
        y = self.winfo_y() + self.text_area.winfo_y() + event.y
        self.right_click_menu.post(x, y)

    def generate_sub_menus(self, sub_menu_items):
        window_methods = [
            method_name for method_name in dir(self)
            if callable(getattr(self, method_name))
        ]
        tkinter_methods = [
            method_name for method_name in dir(tk.Tk)
            if callable(getattr(tk.Tk, method_name))
        ]

        my_methods = [
            method for method in set(window_methods) - set(tkinter_methods)
        ]
        my_methods = sorted(my_methods)

        for item in sub_menu_items:
            sub_menu = tk.Menu(self.menu,
                               tearoff=0,
                               bg=self.background,
                               fg=self.foreground)
            matching_methods = []
            for method in my_methods:
                if method.startswith(item):
                    matching_methods.append(method)

            for match in matching_methods:
                actual_method = getattr(self, match)
                method_shortcut = actual_method.__doc__.strip()
                friendly_name = ' '.join(match.split('_')[1:])
                sub_menu.add_command(label=friendly_name.title(),
                                     command=actual_method,
                                     accelerator=method_shortcut)

            self.menu.add_cascade(label=item.title(), menu=sub_menu)
            self.all_menus.append(sub_menu)

    def show_about_page(self):
        msg.showinfo(
            "About",
            "My text editor, version 2, written in Python3.6 using tkinter!")

    def load_syntax_highlighting_file(self):
        syntax_file = filedialog.askopenfilename(filetypes=[("YAML file",
                                                             ("*.yaml",
                                                              "*.yml"))])
        if syntax_file:
            self.highlighter.clear_highlight()
            self.highlighter = Highlighter(self.text_area, syntax_file)
            self.highlighter.force_highlight()

    def load_scheme_file(self, scheme):
        with open(scheme, 'r') as stream:
            try:
                config = yaml.load(stream)
            except yaml.YAMLError as error:
                print(error)
                return

        self.foreground = config['foreground']
        self.background = config['background']
        self.text_foreground = config['text_foreground']
        self.text_background = config['text_background']

    def load_font_file(self, file_path):
        with open(file_path, 'r') as stream:
            try:
                config = yaml.load(stream)
            except yaml.YAMLError as error:
                print(error)
                return

        self.font_family = config['family']
        self.font_size = config['size']

    def change_colour_scheme(self):
        ColourChooser(self)

    def apply_colour_scheme(self, foreground, background, text_foreground,
                            text_background):
        self.text_area.configure(fg=text_foreground, bg=text_background)
        self.background = background
        self.foreground = foreground
        for menu in self.all_menus:
            menu.configure(bg=self.background, fg=self.foreground)
        self.configure_ttk_elements()

    def configure_ttk_elements(self):
        style = ttk.Style()
        style.configure('editor.TLabel',
                        foreground=self.foreground,
                        background=self.background)
        style.configure('editor.TButton',
                        foreground=self.foreground,
                        background=self.background)

    def change_font(self):
        FontChooser(self)

    def update_font(self):
        self.load_font_file(self.font_scheme_path)
        self.text_area.configure(font=(self.font_family, self.font_size))

    def create_config_directory_if_needed(self):
        if not os.path.exists(self.config_dir):
            os.mkdir(self.config_dir)
            os.mkdir(os.path.join(self.config_dir, 'schemes'))
            os.mkdir(os.path.join(self.config_dir, 'languages'))

        self.create_default_scheme_if_needed()
        self.create_font_scheme_if_needed()
        self.create_python_language_if_needed()

    def create_default_scheme_if_needed(self):
        if not os.path.exists(self.default_scheme_path):
            yaml_file_contents = f"background: 'lightgrey'\n" \
                             + f"foreground: 'black'\n" \
                             + f"text_background: 'white'\n" \
                             + f"text_foreground: 'black'\n"

            with open(self.default_scheme_path, 'w') as yaml_file:
                yaml_file.write(yaml_file_contents)

    def create_font_scheme_if_needed(self):
        if not os.path.exists(self.font_scheme_path):
            yaml_file_contents = f"family: Ubuntu Mono\n" \
                               + f"size: 14"

            with open(self.font_scheme_path, 'w') as yaml_file:
                yaml_file.write(yaml_file_contents)

    def create_python_language_if_needed(self):
        if not os.path.exists(self.python_language_path):
            yaml_file_contents = """
categories:
  keywords:
    colour: orange
    matches: [for, def, while, from, import, as, with, self]

  variables:
    colour: red4
    matches: ['True', 'False', None]

  conditionals:
    colour: green
    matches: [try, except, if, else, elif]

  functions:
    colour: blue4
    matches: [int, str, dict, list, set, float]

numbers:
  colour: purple

strings:
  colour: '#e1218b'
"""
            with open(self.python_language_path, 'w') as yaml_file:
                yaml_file.write(yaml_file_contents)

    # =========== Menu Functions ==============

    def file_new(self, event=None):
        """
        Ctrl+N
        """
        self.text_area.delete(1.0, tk.END)
        self.open_file = None
        self.line_numbers.force_update()

    def file_open(self, event=None):
        """
        Ctrl+O
        """
        file_to_open = filedialog.askopenfilename()
        if file_to_open:
            self.open_file = file_to_open

            self.text_area.display_file_contents(file_to_open)
            self.highlighter.force_highlight()
            self.line_numbers.force_update()

    def file_save(self, event=None):
        """
        Ctrl+S
        """
        current_file = self.open_file if self.open_file else None
        if not current_file:
            current_file = filedialog.asksaveasfilename()

        if current_file:
            contents = self.text_area.get(1.0, tk.END)
            with open(current_file, 'w') as file:
                file.write(contents)

    def edit_cut(self, event=None):
        """
        Ctrl+X
        """
        self.text_area.event_generate("<Control-x>")
        self.line_numbers.force_update()
        self.highlighter.force_highlight()

    def edit_paste(self, event=None):
        """
        Ctrl+V
        """
        self.text_area.event_generate("<Control-v>")
        self.line_numbers.force_update()
        self.highlighter.force_highlight()

    def edit_copy(self, event=None):
        """
        Ctrl+C
        """
        self.text_area.event_generate("<Control-c>")

    def edit_select_all(self, event=None):
        """
        Ctrl+A
        """
        self.text_area.event_generate("<Control-a>")

    def edit_find_and_replace(self, event=None):
        """
        Ctrl+F
        """
        self.show_find_window()

    def edit_undo(self, event=None):
        """
        Ctrl+Z
        """
        self.text_area.event_generate("<Control-z>")
        self.line_numbers.force_update()
        self.highlighter.force_highlight()

    def edit_redo(self, event=None):
        """
        Ctrl+Y
        """
        self.text_area.event_generate("<Control-y>")
        self.line_numbers.force_update()
        self.highlighter.force_highlight()

    def help_about(self, event=None):
        """
        Ctrl+H
        """
        self.show_about_page()

    def tools_change_syntax_highlighting(self, event=None):
        """
        Ctrl+M
        """
        self.load_syntax_highlighting_file()

    def tools_change_colour_scheme(self, event=None):
        """
        Ctrl+G
        """
        self.change_colour_scheme()

    def tools_change_font(self, event=None):
        """
        Ctrl+L
        """
        self.change_font()
Ejemplo n.º 36
0
    def __init__(self):
        QtGui.QMainWindow.__init__(self)

        self.doctree=None
        self.lineMarks={}

        # We put things we want rendered here
        self.render_queue = Queue()
        # We get things rendered back
        self.pdf_queue = Queue()
        # We get doctrees for the outline viewer
        self.doctree_queue = Queue()

        print('Starting background renderer...', end=' ')
        self.renderProcess=Process(target = renderQueue,
            args=(self.render_queue, self.pdf_queue, self.doctree_queue))
        self.renderProcess.daemon=True
        self.renderProcess.start()
        print('DONE')

        # This is always the same
        self.ui=Ui_MainWindow()
        self.ui.setupUi(self)

        # Adjust column widths in the structure tree
        self.ui.tree.header().setStretchLastSection(False)
        self.ui.tree.header().setResizeMode(0, QtGui.QHeaderView.Stretch)
        self.ui.tree.header().setResizeMode(1, QtGui.QHeaderView.ResizeToContents)

        self.pdf=PDFWidget()

        self.ui.pageNum = QtGui.QSpinBox()
        self.ui.pageNum.setMinimum(1)
        self.ui.pageNum.setValue(1)
        self.connect(self.pdf,QtCore.SIGNAL('pageCount'),
            self.ui.pageNum.setMaximum)
        self.connect(self.pdf,QtCore.SIGNAL('pageChanged'),
            self.ui.pageNum.setValue)
        self.connect(self.ui.pageNum,QtCore.SIGNAL('valueChanged(int)'),
            self.pdf.gotoPage)

        self.ui.actionShow_ToolBar=self.ui.toolBar.toggleViewAction()
        self.ui.actionShow_ToolBar.setText("Show Main Toolbar")
        self.ui.menuView.addAction(self.ui.actionShow_ToolBar)

        self.ui.pdfbar.addAction(self.pdf.ui.previous)
        self.ui.pdfbar.addWidget(self.ui.pageNum)
        self.ui.pdfbar.addAction(self.pdf.ui.__next__)
        self.ui.pdfbar.addSeparator()
        self.ui.pdfbar.addAction(self.pdf.ui.zoomin)
        self.ui.pdfbar.addAction(self.pdf.ui.zoomout)
        self.ui.actionShow_PDFBar=self.ui.pdfbar.toggleViewAction()
        self.ui.actionShow_PDFBar.setText("Show PDF Toolbar")
        self.ui.menuView.addAction(self.ui.actionShow_PDFBar)

        self.ui.dockLayout.addWidget(self.ui.pdfbar)
        self.ui.dockLayout.addWidget(self.pdf)
        self.ui.dock.hide()
        self.ui.actionShow_PDF=self.ui.dock.toggleViewAction()
        self.ui.actionShow_PDF.setText('Show Preview')
        self.ui.menuView.addAction(self.ui.actionShow_PDF)
        self.ui.actionShow_Structure=self.ui.structure.toggleViewAction()
        self.ui.actionShow_Structure.setText('Show Document Outline')
        self.ui.menuView.addAction(self.ui.actionShow_Structure)

        self.text_md5=''
        self.style_md5=''

        self.hl1 = Highlighter(self.ui.text.document(),'rest')
        self.hl2 = Highlighter(self.ui.style.document(),'javascript')

        self.editorPos=QtGui.QLabel()
        self.ui.statusBar.addWidget(self.editorPos)
        self.editorPos.show()

        self.statusMessage=QtGui.QLabel()
        self.ui.statusBar.addWidget(self.statusMessage)
        self.statusMessage.show()

        self.on_text_cursorPositionChanged()
        self.on_actionRender_triggered()

        # Connect editing actions to the editors
        self.ui.text.undoAvailable.connect(self.ui.actionUndo1.setEnabled)
        self.ui.actionUndo1.triggered.connect(self.ui.text.undo)
        self.ui.text.redoAvailable.connect(self.ui.actionRedo1.setEnabled)
        self.ui.actionRedo1.triggered.connect(self.ui.text.redo)

        self.ui.text.copyAvailable.connect(self.ui.actionCopy1.setEnabled)
        self.ui.actionCopy1.triggered.connect(self.ui.text.copy)
        self.ui.text.copyAvailable.connect(self.ui.actionCut1.setEnabled)
        self.ui.actionCut1.triggered.connect(self.ui.text.cut)
        self.ui.actionPaste1.triggered.connect(self.ui.text.paste)


        self.ui.style.undoAvailable.connect(self.ui.actionUndo2.setEnabled)
        self.ui.actionUndo2.triggered.connect(self.ui.style.undo)
        self.ui.style.redoAvailable.connect(self.ui.actionRedo2.setEnabled)
        self.ui.actionRedo2.triggered.connect(self.ui.style.redo)

        self.ui.style.copyAvailable.connect(self.ui.actionCopy2.setEnabled)
        self.ui.actionCopy2.triggered.connect(self.ui.style.copy)
        self.ui.style.copyAvailable.connect(self.ui.actionCut2.setEnabled)
        self.ui.actionCut2.triggered.connect(self.ui.style.cut)
        self.ui.actionPaste2.triggered.connect(self.ui.style.paste)

        self.clipBoard=QtGui.QApplication.clipboard()
        self.clipBoard.changed.connect(self.clipChanged)

        self.hookEditToolbar(self.ui.text)
        self.clipChanged(QtGui.QClipboard.Clipboard)

        self.text_fname=None
        self.style_fname=None
        self.pdf_fname=None

        self.ui.searchbar.setVisible(False)
        self.ui.searchWidget=SearchWidget()
        self.ui.searchbar.addWidget(self.ui.searchWidget)
        self.ui.actionFind.triggered.connect(self.ui.searchbar.show)
        self.ui.actionFind.triggered.connect(self.ui.searchWidget.ui.text.setFocus)
        self.ui.searchWidget.ui.close.clicked.connect(self.ui.searchbar.hide)
        self.ui.searchWidget.ui.close.clicked.connect(self.returnFocus)
        self.ui.searchWidget.ui.next.clicked.connect(self.doFind)
        self.ui.searchWidget.ui.previous.clicked.connect(self.doFindBackwards)

        self.updatePdf()

        self.renderTimer=QtCore.QTimer()
        self.renderTimer.timeout.connect(self.on_actionRender_triggered)
        self.renderTimer.start(5000)
class HighlighterTest(unittest.TestCase):


    def setUp(self):
        doc = "This is my review on Panchos Mexican Restaurant. This is only a "
        doc = doc + "test of the emergency broadcasting system. The best "
        doc = doc + "tacos I've ever had were from Panchos. This sentence is "
        doc = doc + "about nothing. Great tacos, burritos, and enchaladas. "
        doc = doc + "Bean burritos are also good. Lots more filler text here. "
        doc = doc + "The filler text in this sentence is muy bueno. Remember to "
        doc = doc + "eat lots of tacos."
        self.doc = doc
        self.query = "tacos burritos enchaladas"
        self.hi = Highlighter(self.doc, self.query)


    def test_tokenize_query_terms(self):
        tokens_result = self.hi.tokenize_query_terms()
        expected_result = ["tacos", "burritos", "enchaladas"]
        #print(tokens_result)
        self.assertEqual(expected_result, tokens_result, tokens_result)


    def test_query_term_density(self):
        query_terms = self.hi.tokenize_query_terms()
        query_term_partial_density = self.hi.query_term_partial_density()
        total_query_term_density = self.hi.query_term_density(query_term_partial_density)
        expected_result = [
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0.2, 0.2, 0.2, 0.2, 0.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.2, 0.2, 0.2, 0.2, 0.2,
            0, 0, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0, 0, 0, 0, 0, 0, 0.1, 0.1,
            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0, 0, 0, 0, 0, 0, 0, 0.125, 0.125, 0.125, 0.125,
            0.125, 0.125, 0.125, 0.125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0.2, 0.2, 0.2, 0.2, 0.2, 0
            ]
        #print(total_query_term_density)
        self.assertEqual(total_query_term_density, expected_result, total_query_term_density)


    def test_max_term_density_window(self):
        query_terms = self.hi.tokenize_query_terms()
        query_term_partial_density = self.hi.query_term_partial_density()
        total_query_term_density = self.hi.query_term_density(query_term_partial_density)
        result_window = self.hi.max_term_density_window(total_query_term_density)
        self.assertTrue(0 <= result_window[0] < result_window[1], "Failed basic windowing.")
        self.assertTrue(self.hi.maximum_snippit_length >= result_window[1] - result_window[0], "Window width too large.")


    def test_highlight_document(self):
        highlighted_result = self.hi.highlight_document()
        #print(highlighted_result)
        self.assertTrue(highlighted_result, highlighted_result)


    def test_highlight_doc(self):
        highlighted_result = Highlighter.highlight_doc(self.doc, self.query)
        msg = "\nhighlighted_result =\n" + highlighted_result
        expected_result = " [[HIGHLIGHT]]tacos[[HIGHLIGHT]] I've ever had were from Panchos. "
        expected_result = expected_result + "This sentence is about nothing. Great [[HIGHLIGHT]]"
        expected_result = expected_result + "tacos burritos[[HIGHLIGHT]], and [[HIGHLIGHT]]"
        expected_result = expected_result + "enchaladas[[HIGHLIGHT]]. Bean [[HIGHLIGHT]]burritos[[HIGHLIGHT]]"
        msg = msg + "\nexpected_result = \n" + expected_result
        self.assertEquals(expected_result, highlighted_result, msg)
Ejemplo n.º 38
0
class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title('THEE')
        self.minsize(550, 40)  # (width, height)
        self.winfo_screenwidth = self.winfo_screenwidth()
        self.winfo_screenheight = self.winfo_screenheight()
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)
        self.width = int(self.winfo_screenwidth / 3)
        self.height = int(self.winfo_screenheight / 3)
        self.geometry(f'{self.width}x{self.height}')

        self.thee_mode = 0  # 0: welcome, 1: editor, 2: terminal, 3: help
        self.count_text_changed = 0
        self.editor_mode_buffer = ""
        self.terminal_mode_buffer = ""
        self.key_buffer = []

        self.file_name = "untitled"
        self.status = "unsaved"
        self.spaces = 4
        self.line = 1
        self.column = 1

        self.foreground = config.color['foreground']
        self.background = config.color['background']
        self.text_foreground = config.color['text_foreground']
        self.text_background = config.color['text_background']
        self.insertbackground = config.color['insertbackground']
        self.statusbar_background = config.color['statusbarbg']

        self.frame1 = tk.Frame(self,
                               bg=self.background,
                               width=self.width,
                               height=self.height - 15)
        self.frame2 = tk.Frame(self,
                               bg=self.statusbar_background,
                               width=self.width,
                               height=10)

        self.frame1.grid(row=0, column=0, sticky='wens')
        self.frame2.grid(row=1, column=0, sticky='wens')

        self.frame1.grid_columnconfigure(1, weight=1)
        self.frame1.grid_rowconfigure(0, weight=1)

        self.config_dir = os.path.join(str(Path.home()), '.thee')

        self.text_font_size = config.font['text']['size']
        self.text_font_family = config.font['text']['family']

        self.statusbar_font_size = config.font['statusbar']['size']
        self.statusbar_font_family = config.font['statusbar']['family']

        self.create_widget()  # Entry point ==========#
        self.terminal = Terminal(self, self.text_area)  # run terminal

        self.bind_events()

        self.open_file = ''

        self.protocol("WM_DELETE_WINDOW", self.close_window)

    def create_widget(self):
        self.text_area = TextArea(self.frame1,
                                  bg=self.text_background,
                                  fg=self.text_foreground,
                                  undo=True,
                                  relief=tk.FLAT,
                                  font=(self.text_font_family,
                                        self.text_font_size),
                                  insertbackground=self.insertbackground)
        self.text_area.config(highlightthickness=0)
        self.text_area.grid(row=0, column=1, sticky='wens')
        self.text_area.focus_set()
        self.welcome(event=None)

        self.status_bar1 = StatusBar(self.frame2,
                                     bg="pink",
                                     width=30,
                                     height=10)
        self.status_bar2 = StatusBar(self.frame2,
                                     bg="orange",
                                     width=30,
                                     height=10)
        self.status_bar3 = StatusBar(self.frame2,
                                     bg="blue",
                                     width=30,
                                     height=10)
        self.status_bar4 = StatusBar(self.frame2,
                                     bg="green",
                                     width=30,
                                     height=10)
        self.status_bar5 = StatusBar(self.frame2,
                                     bg="purple",
                                     width=30,
                                     height=10)

        self.status_bar1.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.status_bar2.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.status_bar3.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.status_bar4.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.status_bar5.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

    def editor_mode(self, event=None):
        self.text_area.config(state=tk.NORMAL, tabs=4)
        self.text_area.delete('1.0', tk.END)
        self.text_area.insert(tk.END, self.editor_mode_buffer)
        self.highlighter = Highlighter(self.text_area)
        self.thee_mode = 1

        self.line_numbers = LineNumbers(self.frame1, self.text_area)
        self.line_numbers.config(bg=self.text_background,
                                 width=len(self.line_numbers.line_number) * 10,
                                 highlightthickness=0)
        self.line_numbers.grid(row=0, column=0, sticky='ns')

        self.status_bar1.set("Line %d, Column %d" % (self.line, self.column))
        self.status_bar3.set("%s" % self.file_name)
        self.status_bar4.set("Spaces: %d" % self.spaces)
        self.status_bar5.set("%s" % self.status)

    def terminal_mode(self, event=None):
        if self.thee_mode == 1:
            self.line_numbers.destroy()
        self.text_area.config(state=tk.NORMAL, tabs=4)
        self.text_area.delete('1.0', tk.END)
        self.text_area.insert(tk.END, self.terminal_mode_buffer)
        self.terminal.writeLoop()
        self.highlighter = Highlighter(self.text_area)
        self.thee_mode = 2

    def text_been_modified(self, event=None):
        flag = self.text_area.edit_modified()
        if flag:  # prevent from getting called twice
            if self.thee_mode == 1 and self.count_text_changed > 1:  # editor mode
                self.editor_mode_buffer = self.text_area.get(
                    1.0, tk.END + "-1c")
                self.status = "unsaved"
                self.status_bar5.set("%s" % self.status)
                self.update_line_column()
                self.line_numbers.config(
                    width=len(self.line_numbers.line_number) * 10)
            elif self.thee_mode == 2 and self.count_text_changed > 1:  # terminal mode
                self.terminal_mode_buffer = self.text_area.get(
                    1.0, tk.END + "-1c")
            self.count_text_changed += 1
        #reset so this will be called on the next change
        self.text_area.edit_modified(False)

    def retrieve_selected_line(self, event=None):
        if self.thee_mode == 1:
            self.current_line = self.text_area.get("1.0", 'end').rstrip()
            if event.keysym.isnumeric():
                self.key_buffer.append(event.keysym)
                # check buffer after 500ms (0.5s)
                self.after(500, self.selected_line_action)

    def selected_line_action(self):
        if self.key_buffer:
            index = int(''.join(self.key_buffer)) - 1
            self.key_buffer.clear()
            self.selected_line = self.current_line.split('\n')[index]
            selected_str = self.selected_line + "\n"
            # write selected code line(s) to the console in order to it running
            self.terminal.proc.stdin.write(selected_str.encode())
            self.terminal.proc.stdin.flush()
            self.terminal_mode()

    def update_line_column(self, event=None):
        if self.thee_mode == 1:
            line, column = self.text_area.index(tk.INSERT).split('.')
            self.line = int(line)
            self.column = int(column) + 1
            self.status_bar1.set("Line %d, Column %d" %
                                 (self.line, self.column))

    def close_window(self):
        if self.editor_mode_buffer and self.status == "unsaved":  #and self.status.get() == "unsaved": #SATUSBAR
            if msg.askokcancel("Quit", "Would you like to save the data?"):
                self.file_save()
                self.terminal.alive = False
                self.terminal.destroy()
            else:
                self.terminal.alive = False
                self.terminal.destroy()
        else:
            self.terminal.alive = False
            self.terminal.destroy()

    def bind_events(self):
        self.focus_set()
        self.text_area.bind_all('<<Modified>>', self.text_been_modified)
        self.text_area.bind('<Return>', self.enter)
        self.bind_all('<Button-1>', self.update_line_column)

        self.bind_all('<Control-e>', self.editor_mode)
        self.bind_all('<Control-t>', self.terminal_mode)
        self.bind_all('<Control-Key>', self.retrieve_selected_line)
        self.bind('<Control-f>', self.show_find_window)

        self.bind('<Control-n>', self.file_new)
        self.bind('<Control-o>', self.file_open)
        self.bind('<Control-s>', self.file_save)
        self.bind('<Control-S>', self.file_save_as)

        self.bind('<Control-w>', self.welcome)
        self.bind('<Control-h>', self.help_about)

    def enter(self, event=None):
        if self.thee_mode == 2:
            self.terminal.enter()

    def show_find_window(self, event=None):
        FindWindow(self.frame1, self.text_area)

    def show_welcome_page(self):
        if self.thee_mode == 1:
            self.line_numbers.destroy()
        self.text_area.config(state=tk.NORMAL)
        self.text_area.delete('1.0', tk.END)
        message = '''
   		\n\n
   		            THEE

   		         version 1.0

   	   THE simple python key bindings  Editor

   	     type   Ctrl-h 	for help information

   	by Fidel R. Monteiro <*****@*****.**>
   		\n

   	    The Pynosso Project | Sat, Jun 26 2020 
   		'''
        self.text_area.insert(tk.END, message)
        self.text_area.config(state=tk.DISABLED)
        self.thee_mode = 0

    def show_about_page(self):
        if self.thee_mode == 1:
            self.line_numbers.destroy()
        self.text_area.config(state=tk.NORMAL)
        self.text_area.delete('1.0', tk.END)
        message = '''
                        HELP

        Mode Commands
            Ctrl+e : Text mode
            Ctrl+t : Terminal mode
            Ctrl+<number> : Run selected line in python console

        Editing Commands
            Ctrl+a : Select all text
            Ctrl+x : Cut selected text
            Ctrl+c : Copy selected text
            Ctrl+v : Paste cut/copied text
            Ctrl+z : Undo
            Ctrl+y : Redo

        File Commands
            Ctrl+o : Open file
            Ctrl+s : Save current content
            Ctrl+S : Save current content as <filename>
            Ctrl+p : Print current content
            Ctrl+n : Open new file

        General
            Ctrl+m : Change syntax highlighting
            Ctrl+g : Change colour scheme
            Ctrl+l : Change font
            Ctrl+h : Display this help window

        AUTHOR
                Written by Fidel R. Monteiro (fm65)
                Sat, Jun 26 2020

        thee version 1.0

        "simple is better than complex"
        '''
        self.text_area.insert(tk.END, message)
        self.text_area.config(state=tk.DISABLED)
        self.thee_mode = 3

    def apply_colour_scheme(self, foreground, background, text_foreground,
                            text_background):
        self.text_area.configure(fg=text_foreground, bg=text_background)
        self.background = background
        self.foreground = foreground
        for menu in self.all_menus:
            menu.configure(bg=self.background, fg=self.foreground)

    def update_font(self):
        #self.load_font_file(self.font_scheme_path)
        self.text_area.configure(font=(self.text_font_family,
                                       self.text_font_size))

    def create_config_directory_if_needed(self):
        if not os.path.exists(self.config_dir):
            os.mkdir(self.config_dir)

    # =========== Menu Functions ==============

    def file_new(self, event=None):
        """
        Ctrl+N
        """
        self.text_area.delete(1.0, tk.END)
        self.open_file = None
        self.editor_mode()
        self.line_numbers.force_update()

    def file_open(self, event=None):
        """
        Ctrl+O
        """
        self.editor_mode()
        file_to_open = filedialog.askopenfilename(filetypes=[('Python files',
                                                              '*.py')],
                                                  defaultextension='.py')
        if file_to_open:
            self.open_file = file_to_open
            self.file_name = self.open_file.split('/')[-1]
            self.status_bar3.set("%s" % self.file_name)

            self.text_area.display_file_contents(file_to_open)
            self.highlighter.force_highlight()
            self.line_numbers.force_update()

    def file_save(self, event=None):
        """
        Ctrl+s
        """
        current_file = self.open_file if self.open_file else None
        if not current_file:
            current_file = filedialog.asksaveasfilename(filetypes=[
                ('Python files', '*.py')
            ],
                                                        defaultextension='.py')
            self.open_file = current_file
            self.file_name = current_file.split('/')[-1]
            self.status_bar3.set("%s" % self.file_name)

        if current_file:
            contents = self.text_area.get(1.0, tk.END)
            with open(current_file, 'w') as file:
                file.write(contents)
                self.status = "saved"
                self.status_bar5.set("%s" % self.status)

    def file_save_as(self, event=None):
        """
        Ctrl+S
        """
        new_file_name = filedialog.asksaveasfilename(filetypes=[
            ('Python files', '*.py')
        ],
                                                     defaultextension='.py',
                                                     confirmoverwrite=False)
        f = open(self.new_file_name, 'w')
        f.write(self.get('1.0', 'end'))
        f.close()
        self.status = "saved"
        self.status_bar5.set("%s" % self.status)

    def edit_cut(self, event=None):
        """
        Ctrl+X
        """
        self.text_area.event_generate("<Control-x>")
        self.line_numbers.force_update()

    def edit_paste(self, event=None):
        """
        Ctrl+V
        """
        self.text_area.event_generate("<Control-v>")
        self.line_numbers.force_update()
        self.highlighter.force_highlight()

    def edit_copy(self, event=None):
        """
        Ctrl+C
        """
        self.text_area.event_generate("<Control-c>")

    def edit_select_all(self, event=None):
        """
        Ctrl+A
        """
        self.text_area.event_generate("<Control-a>")

    def edit_find_and_replace(self, event=None):
        """
        Ctrl+F
        """
        self.show_find_window()

    def welcome(self, event=None):
        """
        Ctrl+W
        """
        self.show_welcome_page()

    def help_about(self, event=None):
        """
        Ctrl+H
        """
        self.show_about_page()
Ejemplo n.º 39
0
    class Script:

        def __init__(self, console, simulation_keywords):
            self.simulation_keywords = simulation_keywords
            self.gui = Gtk.Table()
            self.window = Gtk.ScrolledWindow()
            self.console = console

            self.prevent_button_update = False
            self._textview = Gtk.TextView()

            self._textbuffer = GtkSource.Buffer()
            self._textview.set_buffer(self._textbuffer)

            self._textbuffer.set_max_undo_levels(-1)
            self._textbuffer.set_undo_manager(None)

            self._textbuffer.connect("changed", self.on_text_changed)
            self._textbuffer.connect("paste-done", self.on_text_changed)

            self.error_tag = self._textbuffer.create_tag("error", background="orange")

            font_description = Pango.FontDescription("monospace 9")
            self._textview.modify_font(font_description)

            misc.set_tabs(self._textview, font_description, 4)

            self.window.set_shadow_type(Gtk.ShadowType.IN)
            misc.gtk_set_margin(self.gui, 5, top=10)

            # Init highlight:
            self.highlight = Highlighter(self._textbuffer)
            self.load_highlight()

            self.error_bar = Gtk.InfoBar()
            self.error_bar_label = Gtk.Label()
            self.error_bar.get_content_area().add(self.error_bar_label)
            self.error_bar_label.show()

            self.error_bar.set_message_type(Gtk.MessageType.ERROR)

            self.window.add(self._textview)
            #self.error_bar.set_size_request(80, 100)

            self.gui.attach(self.window, 0, 8, 0, 1)
            self.gui.attach(self.error_bar, 8, 10, 0, 1)

            self.error_bar.set_no_show_all(True)

            # Init script
            self.load_simulation("./simulations/welcome.py")


        def on_text_changed(self, x='', y=''):
            self.highlight.perform()
            error = None
            if hasattr(self.console, "controls"):
                error = self.console.controls.refresh()

            if not error:
                if self.prevent_button_update:
                    self.prevent_button_update = False
                else:
                    self.try_update_button_states()
                if hasattr(self.console, "controls"):
                    self.error_bar.hide()
            else:
                error_name = error[0]
                exception = error[1]
                line = error[2]
                self.highlight_error_line(line)
                if hasattr(self.console, "controls"):

                    messsage = _(error_name)
                    messsage = '<span weight="bold">' + _(error_name) + ':</span>\n'

                    if error_name in ["IndentationError", "SyntaxError"]:
                        #pos = exception[1][2]
                        #wrong_line = exception[1][3]
                        messsage += "\n" + _(exception[0])
                        #messsage += "\n" + '<span style="italic">' + wrong_line + '</span>'
                    elif error_name in ["NameError"]:
                        name = exception[0][6:][:-16]
                        messsage += "\n" + _("name '%s' is not defined") % name
                    elif error_name in ["AttributeError"]:
                        match = re.search("no attribute '(.*?)'", exception[0])
                        name = match.group(1)
                        match = re.search("'(.*?)' object", exception[0])
                        obj = match.group(1)
                        messsage += "\n" + _("'%s' object has no attribute '%s'") % (obj, name)
                    else:
                        messsage += "\n" + str(exception)
                        print exception.args

                    self.error_bar_label.set_markup('<span foreground="black">' + messsage + '</span>')

                    self.error_bar.show()

        def get_functions_data(self, name, max_args=0):

            script = self.get_script()
            functions = []

            reg_str = name + "\("
            for i in xrange(max_args):
                reg_str += "("

                if i > 0:
                    reg_str += ",\s*"
                reg_str += "(.*?)"
                reg_str += ")?"
            reg_str += "\)"

            regexp_object = re.compile(reg_str)

            for match in regexp_object.finditer(script):

                entry = []

                d = {
                    'element': match.group(0),
                    'start': match.start(0),
                    'end': match.end(0)
                }

                entry.append( d )

                for i in xrange(max_args):
                    try:
                        arg = eval(match.group(2 + 2*i))
                    except:
                        arg = False
                    entry.append(arg)

                functions.append(entry)

            return functions

        def try_update_button_states(self):

            # 1. Let
            # regexp wyszukujacy let(option_name, value_from_script),
            # Z zapisem do listy register w postaci rekordow:
            # register[option_name] = value_from_script
            register_change = {}

            lets_data = self.get_functions_data('let', 2)

            for data in lets_data:
                if data[1] and data[2]:

                    value = False

                    try:
                        option_name = data[1]
                        value = data[2]
                        register_change[option_name] = value
                    except:
                        pass

            # pobieram z option_browsera informacje o dostepnych let-ach
            # i ustawiam wszystkie na False. Potem aktualizuje liste dostepnych
            # let-ow lista register (aby wyeliminowac usuniete w skrypcie let-y)
            available = self.console.option_browser.get_let_actions_list()

            register = {}

            for let in available:
                register[let] = False

            register.update(register_change)

            register = register.items()

            self.console.option_browser.update_button_states_from_register(register)
            # 2. ...

        def undo(self):
            if self._textbuffer.can_undo():
                self._textbuffer.undo()

        def redo(self):
            if self._textbuffer.can_redo():
                self._textbuffer.redo()

        def insert(self, *args, **kwargs):
            self.insert_or_modify(True, *args, **kwargs)

        def modify(self, *args, **kwargs):
            """
            try to find object specified by identity of x first arguments
            and modify them (where x is given by 'identities' keyword argument)
            otherwise add new object with specified variables
            """
            self.insert_or_modify(False, *args, **kwargs)

        def insert_or_modify(self, force_new_instance, *args, **kwargs):
            """

            where - on_top, on_bottom, after_comments
            into - script_body, <function_name>

            """
            # whether to insert new instances on top or bottom of script
            where = kwargs.pop('where', "on_bottom")
            into = kwargs.pop('into', "script_body")

            # if the force_new_instance is true,
            # we will not modify exiting objects, but always add new
            # otherwise it will modify all existing object of specified
            # (by first 'non-self' positional argument) name.
            # It's possible to specify number of arguments that have to be identical,
            # to modify existing a function

            identities = kwargs.pop('identities', 1)

            args = list(args)
            object_type = args.pop(0)
            name = args.pop(0)

            if object_type in ["function", "object"]:
                new_func = misc.create_function_str(name, *args)

                if force_new_instance:
                    return self.insert_into_buffer(new_func, where, into)

                replaced = False

                if identities > len(args):
                    raise Exception("Wrong arguments: identities higher than number of non-special arguments (all arguments excep self, object_type and name)")

                data_list = self.get_functions_data(name, len(args))

                for data in data_list:
                    good_match = True
                    for i in xrange(identities):
                        if args[i] != data[1 + i]:
                            good_match = False
                    if good_match:
                        self.replace_on_pos(data[0]["start"], data[0]["end"], new_func)
                        replaced = True

                if not replaced:
                    return self.insert_into_buffer(new_func, where, into)

            #if obj_type == class_function: (ball.push(...))
            #if obj_type == class_property: (ball.velocity = ...)
            #if obj_type == comment: (# name = Nazwa symulacji)

            else:
                raise ValueError("object_type: " + str(object_type) + " is not defined")

        def replace_on_pos(self, start, end, new_text):
            start = self._textbuffer.get_iter_at_offset(start)
            end = self._textbuffer.get_iter_at_offset(end)
            self.prevent_button_update = True
            self._textbuffer.delete(start, end)
            self.prevent_button_update = True
            self._textbuffer.insert(start, new_text)

        def insert_into_buffer(self, new_text, where, into):
            if where in ["on_top", "after_comments"]:

                offset = 0

                if where == "after_comments":

                    script = self.get_script()

                    inside_doc_string = False

                    for line in script.split("\n"):

                        raw_line = line.strip()

                        if not raw_line:
                            offset += len(line) + 1
                            break

                        if inside_doc_string:
                            if raw_line[-3:] == '"""':
                                inside_doc_string = False
                            offset += len(line) + 1
                            continue
                        else:
                            # TODO: could docstring by with '''?
                            if raw_line[:3] == '"""':
                                if raw_line[-3:] != '"""':
                                    inside_doc_string = True
                                offset += len(line) + 1
                                continue

                        # if line is comment
                        if raw_line[0] == "#":
                            offset += len(line) + 1
                        else:
                            if not inside_doc_string:
                                break

                new_text += "\n"
                iterator = self._textbuffer.get_iter_at_offset(offset)
            else:
                iterator = self._textbuffer.get_end_iter()
                new_text = "\n" + new_text

            self._textbuffer.insert(iterator, new_text)

        def highlight_error_line(self, line_number):

            start = self._textbuffer.get_iter_at_line(line_number - 1)
            end = self._textbuffer.get_iter_at_line(line_number)

            self._textbuffer.apply_tag(self.error_tag, start, end)

        def load_simulation(self, path):

            script = misc.file_get_contents(path)

            self.set_script(script)
            self.path = path

        def save_simulation(self, path):
            self.path = path
            script = self.get_script()
            misc.file_put_contents(path, script)

        def load_highlight(self):
            python_tfn = ["None", "True", "False", "-?\d+\.\d+", "-?\d+"]
            python_statements = [
                "nonlocal", "and", "as", "assert", "break", "class", "continue", "def", "del", "elif",
                "else", "except", "exec", "finally", "for", "from", "global", "if", "import", "in",
                "is", "lambda", "raise", "return", "not", "or", "pass", "print", "try", "while", "with", "yield"
            ]
            self.highlight.add_words(python_statements, "statements", foreground="brown", weight=Pango.Weight.BOLD)
            self.highlight.add_words(python_tfn, "tfn", foreground="purple")
            self.highlight.add_words(self.simulation_keywords, "sim_func", foreground="green")
            self.highlight.add([re.compile("(?P<highlight>const)([.]+)")], "const", foreground="green", weight=Pango.Weight.NORMAL)
            self.highlight.add([re.compile("[\"](.*?)[\"]|['](.*?)[']")], "string", foreground="purple", weight=Pango.Weight.NORMAL)
            self.highlight.add([re.compile("def([\s])(?P<highlight>(.*?))\((.*?)\):")], "after_def", foreground="purple", weight=Pango.Weight.NORMAL)
            # comment must be last (color overriding)
            self.highlight.add([re.compile("#(.)*")], "comment", foreground="blue", weight=Pango.Weight.NORMAL)

        def set_script(self, text):

            self._textbuffer.begin_not_undoable_action()
            self._textbuffer.set_text(text)
            self._textbuffer.end_not_undoable_action()

        def get_script(self):

            start_iter = self._textbuffer.get_start_iter()
            end_iter = self._textbuffer.get_end_iter()

            return self._textbuffer.get_text(start_iter, end_iter, True)
Ejemplo n.º 40
0
class MainWindow(tk.Tk):
    '''
    @param tk.TK: Windows、Mac、Unix下TK GUI套件的标准Python接口,可实现GUI界面
    '''

    #窗口设置
    def __init__(self):
        '''
        @update 1.添加横向滚动条 2.修正行号与滚动条和窗口的关联 3.修正行号显示
        '''
        super().__init__()

        self.title('Python Text Editor v3')
        self.geometry('800x600')

        self.foreground = 'black'
        self.background = 'lightgrey'
        self.text_foreground = 'black'
        self.text_background = 'white'

        self.config_dir = os.path.join(str(Path.home()), '.tkedit')

        self.default_scheme_path = os.path.join(self.config_dir,
                                                'schemes/default.yaml')
        self.python_language_path = os.path.join(self.config_dir,
                                                 'languages/python.yaml')
        self.none_language_path = os.path.join(self.config_dir,
                                               'languages/None.yaml')
        self.font_scheme_path = os.path.join(self.config_dir,
                                             'fonts/font.yaml')
        self.create_config_directory_if_needed()

        self.load_scheme_file(self.default_scheme_path)
        self.configure_ttk_elements()

        self.font_size = 15
        self.font_family = "Ubuntu Mono"
        self.load_font_file(self.font_scheme_path)

        self.text_area = TextArea(self,
                                  bg=self.text_background,
                                  fg=self.text_foreground,
                                  undo=True,
                                  font=(self.font_family, self.font_size))

        self.scrollbar = ttk.Scrollbar(orient="vertical",
                                       command=self.text_area.yview)
        self.scrollbar2 = ttk.Scrollbar(orient="horizontal",
                                        command=self.text_area.xview)

        self.line_numbers = LineNumbers(self,
                                        self.text_area,
                                        bg="grey",
                                        fg="white",
                                        width=1,
                                        font=(self.font_family,
                                              self.font_size))
        self.scrollbar.config(command=self.text_area.yview)
        self.text_area.config(yscrollcommand=self.scrollbar.set,
                              xscrollcommand=self.scrollbar2.set)
        self.highlighter = Highlighter(self.text_area, self.none_language_path)

        self.menu = tk.Menu(self, bg=self.background, fg=self.foreground)
        self.all_menus = [self.menu]

        sub_menu_items = ["file", "edit", "tools", "help"]
        self.generate_sub_menus(sub_menu_items)
        self.configure(menu=self.menu)

        self.right_click_menu = tk.Menu(self,
                                        bg=self.background,
                                        fg=self.foreground,
                                        tearoff=0)
        self.right_click_menu.add_command(label='Cut', command=self.edit_cut)
        self.right_click_menu.add_command(label='Copy', command=self.edit_copy)
        self.right_click_menu.add_command(label='Paste',
                                          command=self.edit_paste)
        self.all_menus.append(self.right_click_menu)

        self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.scrollbar2.pack(side=tk.BOTTOM, fill=tk.X)
        self.line_numbers.pack(side=tk.LEFT, fill=tk.Y)
        self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

        self.bind_events()

        self.open_file = ''

    #绑定事件
    def bind_events(self):
        self.text_area.bind("<MouseWheel>", self.scroll_text)
        self.text_area.bind("<Button-4>", self.scroll_text)
        self.text_area.bind("<Button-5>", self.scroll_text)
        self.text_area.bind("<Button-3>", self.show_right_click_menu)

        self.bind('<Control-f>', self.show_find_window)

        self.bind('<Control-n>', self.file_new)
        self.bind('<Control-o>', self.file_open)
        self.bind('<Control-s>', self.file_save)

        self.bind('<Control-h>', self.help_about)

        self.bind('<Control-m>', self.tools_change_syntax_highlighting)
        self.bind('<Control-g>', self.tools_change_colour_scheme)
        self.bind('<Control-l>', self.tools_change_font)

        self.line_numbers.bind("<MouseWheel>", lambda e: "break")
        self.line_numbers.bind("<Button-4>", lambda e: "break")
        self.line_numbers.bind("<Button-5>", lambda e: "break")

    #滚动事件
    def scroll_text(self, *args):
        if len(args) > 1:
            self.text_area.yview_moveto(args[1])
            self.line_numbers.yview_moveto(args[1])
        else:
            event = args[0]
            if event.delta:
                move = -1 * (event.delta / 120)
            else:
                if event.num == 5:
                    move = 1
                else:
                    move = -1

            self.text_area.yview_scroll(int(move), "units")
            self.line_numbers.yview_scroll(int(move) * 3, "units")

    #内容查找、替换窗口
    def show_find_window(self, event=None):
        FindWindow(self.text_area)

    #显示右键菜单
    def show_right_click_menu(self, event):
        x = self.winfo_x() + self.text_area.winfo_x() + event.x
        y = self.winfo_y() + self.text_area.winfo_y() + event.y
        self.right_click_menu.post(x, y)

    #设置子菜单
    def generate_sub_menus(self, sub_menu_items):
        '''
        @param sub_menu_items: 子菜单项目
        '''
        window_methods = [
            method_name for method_name in dir(self)
            if callable(getattr(self, method_name))
        ]
        tkinter_methods = [
            method_name for method_name in dir(tk.Tk)
            if callable(getattr(tk.Tk, method_name))
        ]

        my_methods = [
            method for method in set(window_methods) - set(tkinter_methods)
        ]
        my_methods = sorted(my_methods)

        for item in sub_menu_items:
            sub_menu = tk.Menu(self.menu,
                               tearoff=0,
                               bg=self.background,
                               fg=self.foreground)
            matching_methods = []
            for method in my_methods:
                if method.startswith(item):
                    matching_methods.append(method)

            for match in matching_methods:
                actual_method = getattr(self, match)
                method_shortcut = actual_method.__doc__.strip()
                friendly_name = ' '.join(match.split('_')[1:])
                sub_menu.add_command(label=friendly_name.title(),
                                     command=actual_method,
                                     accelerator=method_shortcut)

            self.menu.add_cascade(label=item.title(), menu=sub_menu)
            self.all_menus.append(sub_menu)

    #显示关于
    def show_about_page(self):
        msg.showinfo(
            "About",
            "My text editor, version 2, written in Python3.6 using tkinter!")

    #加载文字高亮配色方案
    def load_syntax_highlighting_file(self):
        syntax_file = filedialog.askopenfilename(filetypes=[("YAML file",
                                                             ("*.yaml",
                                                              "*.yml"))])
        if syntax_file:
            self.highlighter.clear_highlight()
            self.highlighter = Highlighter(self.text_area, syntax_file)
            self.highlighter.force_highlight()

    #加载窗体配色方案
    def load_scheme_file(self, scheme):
        '''
        @param scheme: 目标配置文件
        @update GSC 预检测
        '''
        with open(scheme, 'r') as stream:
            try:
                config = yaml.load(stream)
            except yaml.YAMLError as error:
                print(error)
                return

        if 'foreground' in config:
            self.foreground = config['foreground']
        if 'background' in config:
            self.background = config['background']
        if 'text_foreground' in config:
            self.text_foreground = config['text_foreground']
        if 'text_background' in config:
            self.text_background = config['text_background']

    #加载字体及字号方案
    def load_font_file(self, file_path):
        '''
        @param file_path: 方案存放路径及文件名
        '''
        with open(file_path, 'r') as stream:
            try:
                config = yaml.load(stream)
            except yaml.YAMLError as error:
                print(error)
                return

        if 'family' in config:
            self.font_family = config['family']
        if 'size' in config:
            self.font_size = config['size']

    #修改窗体配色方案
    def change_colour_scheme(self):
        ColourChooser(self)

    #应用窗体配色方案
    def apply_colour_scheme(self, foreground, background, text_foreground,
                            text_background):
        '''
        @param foreground: 新窗体前景色
        @param background: 新窗体背景色
        @param text_foreground: 新字体前景色
        @param text_background: 新字体背景色
        '''
        self.text_area.configure(fg=text_foreground, bg=text_background)
        self.background = background
        self.foreground = foreground
        for menu in self.all_menus:
            menu.configure(bg=self.background, fg=self.foreground)
        self.configure_ttk_elements()

    #应用按钮、标签配色方案
    def configure_ttk_elements(self):
        style = ttk.Style()
        style.configure('editor.TLabel',
                        foreground=self.foreground,
                        background=self.background)
        style.configure('editor.TButton',
                        foreground=self.foreground,
                        background=self.background)

    #字体选择窗口
    def change_font(self):
        FontChooser(self)

    #更新字体
    def update_font(self):
        '''
        @update 1.添加行号字体更新
        '''
        self.load_font_file(self.font_scheme_path)
        self.text_area.configure(font=(self.font_family, self.font_size))
        self.line_numbers.configure(font=(self.font_family, self.font_size))

    #运行环境检测
    def create_config_directory_if_needed(self):
        if not os.path.exists(self.config_dir):
            os.mkdir(self.config_dir)
        if not os.path.exists(os.path.join(self.config_dir, 'schemes')):
            os.mkdir(os.path.join(self.config_dir, 'schemes'))
        if not os.path.exists(os.path.join(self.config_dir, 'languages')):
            os.mkdir(os.path.join(self.config_dir, 'languages'))
        if not os.path.exists(os.path.join(self.config_dir, 'fonts')):
            os.mkdir(os.path.join(self.config_dir, 'fonts'))

        self.create_default_scheme_if_needed()
        self.create_font_scheme_if_needed()
        self.create_python_language_if_needed()

    #运行环境创建 -- 窗体默认配置方案
    def create_default_scheme_if_needed(self):
        if not os.path.exists(self.default_scheme_path):
            yaml_file_contents = f"background: 'lightgrey'\n" \
                               + f"foreground: 'black'\n" \
                               + f"text_background: 'white'\n" \
                               + f"text_foreground: 'black'\n"

            with open(self.default_scheme_path, 'w') as yaml_file:
                yaml_file.write(yaml_file_contents)

    #运行环境创建 -- 字体默认配置方案
    def create_font_scheme_if_needed(self):
        if not os.path.exists(self.font_scheme_path):
            yaml_file_contents = f"family: Ubuntu Mono\n" \
                               + f"size: 15"

            with open(self.font_scheme_path, 'w') as yaml_file:
                yaml_file.write(yaml_file_contents)

    #运行环境创建 -- 语言文字高亮默认配置方案
    def create_python_language_if_needed(self):
        if not os.path.exists(self.python_language_path):
            yaml_file_contents = """
categories:
  keywords:
    colour: orange
    matches: [for, def, while, from, import, as, with, self]

  variables:
    colour: red4
    matches: ['True', 'False', None]

  conditionals:
    colour: green
    matches: [try, except, if, else, elif]

  functions:
    colour: blue4
    matches: [int, str, dict, list, set, float]

numbers:
  colour: purple

strings:
  colour: '#e1218b'
"""
            with open(self.python_language_path, 'w') as yaml_file:
                yaml_file.write(yaml_file_contents)

        if not os.path.exists(self.none_language_path):
            yaml_file_contents = """

categories:
  keywords:
    colour: black
    matches: [for, def, while, from, import, as, with, self]

  variables:
    colour: black
    matches: ['True', 'False', None]

  conditionals:
    colour: black
    matches: [try, except, if, else, elif]

  functions:
    colour: black
    matches: [int, str, dict, list, set, float]

numbers:
  colour: black

strings:
  colour: black
"""
            with open(self.none_language_path, 'w') as yaml_file:
                yaml_file.write(yaml_file_contents)

    # =========== Menu Functions ==============

    #新建文件
    def file_new(self, event=None):
        """
        Ctrl+N
        """
        self.text_area.delete(1.0, tk.END)
        self.open_file = ""
        self.line_numbers.force_update()

    #打开文件
    def file_open(self, event=None):
        """
        Ctrl+O
        """
        file_to_open = filedialog.askopenfilename()
        if file_to_open:
            self.open_file = file_to_open

            self.text_area.display_file_contents(file_to_open)
            self.highlighter.force_highlight()
            self.line_numbers.force_update()

    #保存文件
    def file_save(self, event=None):
        """
        Ctrl+S
        """
        current_file = self.open_file if self.open_file else None
        if not current_file:
            current_file = filedialog.asksaveasfilename()

        if current_file:
            contents = self.text_area.get(1.0, tk.END)
            with open(current_file, 'w') as file:
                file.write(contents)

    #剪切
    def edit_cut(self, event=None):
        """
        Ctrl+X
        """
        self.text_area.event_generate("<Control-x>")
        self.line_numbers.force_update()

    #粘贴
    def edit_paste(self, event=None):
        """
        Ctrl+V
        """
        self.text_area.event_generate("<Control-v>")
        self.line_numbers.force_update()
        self.highlighter.force_highlight()

    #复制
    def edit_copy(self, event=None):
        """
        Ctrl+C
        """
        self.text_area.event_generate("<Control-c>")

    #全选
    def edit_select_all(self, event=None):
        """
        Ctrl+A
        """
        self.text_area.event_generate("<Control-a>")

    #查找和替换
    def edit_find_and_replace(self, event=None):
        """
        Ctrl+F
        """
        self.show_find_window()

    #帮助与关于
    def help_about(self, event=None):
        """
        Ctrl+H
        """
        self.show_about_page()

    #选择语言(文字高亮)
    def tools_change_syntax_highlighting(self, event=None):
        """
        Ctrl+M
        """
        self.load_syntax_highlighting_file()

    #选择窗体配色
    def tools_change_colour_scheme(self, event=None):
        """
        Ctrl+G
        """
        self.change_colour_scheme()

    #选择字体字号
    def tools_change_font(self, event=None):
        """
        Ctrl+L
        """
        self.change_font()
Ejemplo n.º 41
0
    def __init__(self):
        '''
        @update 1.添加横向滚动条 2.修正行号与滚动条和窗口的关联 3.修正行号显示
        '''
        super().__init__()

        self.title('Python Text Editor v3')
        self.geometry('800x600')

        self.foreground = 'black'
        self.background = 'lightgrey'
        self.text_foreground = 'black'
        self.text_background = 'white'

        self.config_dir = os.path.join(str(Path.home()), '.tkedit')

        self.default_scheme_path = os.path.join(self.config_dir,
                                                'schemes/default.yaml')
        self.python_language_path = os.path.join(self.config_dir,
                                                 'languages/python.yaml')
        self.none_language_path = os.path.join(self.config_dir,
                                               'languages/None.yaml')
        self.font_scheme_path = os.path.join(self.config_dir,
                                             'fonts/font.yaml')
        self.create_config_directory_if_needed()

        self.load_scheme_file(self.default_scheme_path)
        self.configure_ttk_elements()

        self.font_size = 15
        self.font_family = "Ubuntu Mono"
        self.load_font_file(self.font_scheme_path)

        self.text_area = TextArea(self,
                                  bg=self.text_background,
                                  fg=self.text_foreground,
                                  undo=True,
                                  font=(self.font_family, self.font_size))

        self.scrollbar = ttk.Scrollbar(orient="vertical",
                                       command=self.text_area.yview)
        self.scrollbar2 = ttk.Scrollbar(orient="horizontal",
                                        command=self.text_area.xview)

        self.line_numbers = LineNumbers(self,
                                        self.text_area,
                                        bg="grey",
                                        fg="white",
                                        width=1,
                                        font=(self.font_family,
                                              self.font_size))
        self.scrollbar.config(command=self.text_area.yview)
        self.text_area.config(yscrollcommand=self.scrollbar.set,
                              xscrollcommand=self.scrollbar2.set)
        self.highlighter = Highlighter(self.text_area, self.none_language_path)

        self.menu = tk.Menu(self, bg=self.background, fg=self.foreground)
        self.all_menus = [self.menu]

        sub_menu_items = ["file", "edit", "tools", "help"]
        self.generate_sub_menus(sub_menu_items)
        self.configure(menu=self.menu)

        self.right_click_menu = tk.Menu(self,
                                        bg=self.background,
                                        fg=self.foreground,
                                        tearoff=0)
        self.right_click_menu.add_command(label='Cut', command=self.edit_cut)
        self.right_click_menu.add_command(label='Copy', command=self.edit_copy)
        self.right_click_menu.add_command(label='Paste',
                                          command=self.edit_paste)
        self.all_menus.append(self.right_click_menu)

        self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.scrollbar2.pack(side=tk.BOTTOM, fill=tk.X)
        self.line_numbers.pack(side=tk.LEFT, fill=tk.Y)
        self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

        self.bind_events()

        self.open_file = ''
Ejemplo n.º 42
0
 def setupEditor(self):
     self.highlighter = Highlighter(self.ui.mainTextEdit.document())
Ejemplo n.º 43
0
from main import app
from highlighter import Highlighter

if __name__ == "__main__":
    h = Highlighter('hello.py', "print('hello world')")
    h.get_highlighted_code()
    h.get_stylesheet_content()
    h.get_css_id_name()

    print('successfully finished all tests')