<commit_before>#!/usr/bin/env python
# Thanks a lot to nemo_ on irc.gnome.org for help on this and <NAME> for undostack!

import pygtk, gtk, os, re, sys, gobject, copy, pango, ast, tempfile, enchant, undostack
pygtk.require('2.0')

if not os.path.exists(os.path.join(os.path.expanduser('~'), '.config', 'smartte')):
    os.mkdir(os.path.join(os.path.expanduser('~'), '.config', 'smartte'))



class MainWindow(object):
    class BindedTextView(gtk.TextView):
        __gsignals__ = dict(
            keybinding = (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION,
                None,
                (str,))
        )
    gobject.type_register(BindedTextView)
    gtk.binding_entry_add_signal(BindedTextView, gtk.keysyms.C, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, 'keybinding', str, 'ctrl+shift+c')
    gtk.binding_entry_add_signal(BindedTextView, gtk.keysyms.X, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, 'keybinding', str, 'ctrl+shift+x')
    gtk.binding_entry_add_signal(BindedTextView, gtk.keysyms.V, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, 'keybinding', str, 'ctrl+shift+v')


    def keyBindings(self, widget, keyCombo):
        print keyCombo
        if keyCombo == 'ctrl+shift+c':
            self.textCopyTo()
        elif keyCombo == 'ctrl+shift+x':
            self.textConvertFrom(widget)
            outputStart, outputEnd = self.textBuffer.get_selection_bounds()
            self.textBuffer.delete(outputStart, outputEnd)


    def newFile(self, widget, data=None):
        self.textBuffer.set_text('')
        del self.filename


    def genFileFilters(self, fileSel):
        filter = gtk.FileFilter()
        filter.set_name('All Files')
        filter.add_pattern('*')
        fileSel.add_filter(filter)
        filter = gtk.FileFilter()
        filter.set_name('Plain Text+BBCode')
        filter.add_mime_type('text/plain')
        filter.add_pattern('*.txt')
        fileSel.add_filter(filter)


    def openFile(self, widget, data=None):
        fileSel =  gtk.FileChooserDialog(title='Open File', action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        self.genFileFilters(fileSel)
        response = fileSel.run()
        if response == gtk.RESPONSE_OK:
            self.openFileCli(fileSel.get_filename())
            fileSel.destroy()
        elif response == gtk.RESPONSE_CANCEL:
            fileSel.destroy()


    def openFileCli(self, filename):
        self.filename = filename
        File = open(self.filename, 'r')
        tmpFileData = File.read()
        File.close()
        firstLine = tmpFileData[:tmpFileData.find('\n')+1]
        tmpReg = re.compile(r'{*}\n')
        if not tmpReg.search(firstLine) == None:
            self.docSettings = ast.literal_eval(firstLine[:-1])
            fileData = tmpFileData[tmpFileData.find('\n')+1:]
            self.textConvertFrom(fileData)
            if not self.docSettings['ignoreList'] == []:
                for begin, end in self.docSettings['ignoreList']:
                    self.textBuffer.apply_tag_by_name('ignore', self.textBuffer.get_iter_at_offset(begin), self.textBuffer.get_iter_at_offset(end))
            del(self.docSettings['ignoreList'])
            for word in self.docSettings['docDict']:
                self.dict.add(word)
            if self.docSettings['justStyle'] == 'left':
                self.justLeftButton.set_active(True)
            elif self.docSettings['justStyle'] == 'center':
                self.justCenterButton.set_active(True)
            elif self.docSettings['justStyle'] == 'right':
                self.justRightButton.set_active(True)
            elif self.docSettings['justStyle'] == 'fill':
                self.justFillButton.set_active(True)
        else:
            fileData = tmpFileData
            self.textConvertFrom(fileData)
        self.openCheckSpelling()
        self.textBuffer.set_modified(False)
        self.curPos = self.textBuffer.create_mark(None, self.textBuffer.get_iter_at_mark(self.textBuffer.get_insert()))
        self.curOldPos = self.textBuffer.create_mark(None, self.textBuffer.get_iter_at_mark(self.textBuffer.get_insert()))


    def writeFile(self):
        docText = self.textConvertTo()
        tmpSettings = copy.deepcopy(self.docSettings)
        tmpSettings['ignoreList'] = []
        if tmpSettings['saveIgnore']:
            tmpIter = self.textBuffer.get_start_iter()
            if tmpIter.begins_tag(self.ignoreTag):
                beginIter = self.textBuffer.get_iter_at_offset(tmpIter.get_offset())
            else:
                tmpIter.forward_to_tag_toggle(self.ignoreTag)
                beginIter = self.textBuffer.get_iter_at_offset(tmpIter.get_offset())
            tmpIter.forward_to_tag_toggle(self.ignoreTag)
            endIter = tmpIter
            tmpSettings['ignoreList'].append((beginIter.get_offset(), endIter.get_offset()))
            tmpVar = tmpIter.forward_to_tag_toggle(self.ignoreTag)
            while tmpVar:
                beginIter = self.textBuffer.get_iter_at_offset(tmpIter.get_offset())
                tmpIter.forward_to_tag_toggle(self.ignoreTag)
                endIter = tmpIter
                tmpSettings['ignoreList'].append((beginIter.get_offset(), endIter.get_offset()))
                tmpVar = tmpIter.forward_to_tag_toggle(self.ignoreTag)
        finalDoc = str(tmpSettings) + '\n' + docText
        File = open(self.filename, 'w')
        File.write(finalDoc)
        File.close()
        self.textBuffer.set_modified(False)


    def saveAsFile(self, widget, data=None):
        fileSel =  gtk.FileChooserDialog(title='Save File', action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK))
        self.genFileFilters(fileSel)
        saveIgnore = gtk.CheckButton('Save Ignore list with file?')
        saveIgnore.set_active(True)
        saveIgnore.set_tooltip_text('If you choose not to save the list, then you will have to remark them again when you reopen the file.')
        saveIgnore.show()
        fileSel.set_extra_widget(saveIgnore)
        response = fileSel.run()
        if response == gtk.RESPONSE_OK:
            self.filename = fileSel.get_filename()
            self.docSettings['saveIgnore'] = saveIgnore.get_active()
            if os.path.exists(self.filename):
                checkDialog = gtk.MessageDialog(fileSel,gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_NONE, 'The file ' + os.path.basename(self.filename) + ' already exists, are you sure you want to overwrite it?')
                checkDialog.add_button(gtk.STOCK_NO, gtk.RESPONSE_NO)
                checkDialog.add_button(gtk.STOCK_YES, gtk.RESPONSE_YES)
                checkResponse = checkDialog.run()
                if checkResponse == gtk.RESPONSE_YES:
                    fileSel.destroy()
                    checkDialog.destroy()
                    self.writeFile()
                elif checkResponse == gtk.RESPONSE_NO:
                    fileSel.destroy()
                    checkDialog.destroy()
            else:
                fileSel.destroy()
                self.writeFile()
        elif response == gtk.RESPONSE_CANCEL:
            fileSel.destroy()


    def saveFile(self, widget, data=None):
        try: self.filename
        except AttributeError:
            self.saveAsFile(widget)
        else:
            self.writeFile()


    def textConvertTo(self, pos=0):
        def apply_tag(self):
            iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
            if iter.begins_tag(self.boldTag) and not self.boldLock:
                self.tmpBuffer.insert(iter, '[b]')
                self.boldLock = True
            iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
            if iter.begins_tag(self.italTag) and not self.italLock:
                self.tmpBuffer.insert(iter, '[i]')
                self.italLock = True
            iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
            if iter.begins_tag(self.undlTag) and not self.undlLock:
                self.tmpBuffer.insert(iter, '[u]')
                self.undlLock = True
            iter = self.tmpBuffer.get_iter_at_mark(self.endMark)
            if iter.ends_tag(self.boldTag) and self.boldLock:
                self.tmpBuffer.insert(iter, '[/b]')
                self.boldLock = False
            iter = self.tmpBuffer.get_iter_at_mark(self.endMark)
            if iter.ends_tag(self.italTag) and self.italLock:
                self.tmpBuffer.insert(iter, '[/i]')
                self.italLock = False
            iter = self.tmpBuffer.get_iter_at_mark(self.endMark)
            if iter.ends_tag(self.undlTag) and self.undlLock:
                self.tmpBuffer.insert(iter, '[/u]')
                self.undlLock = False
        self.tmpBuffer = gtk.TextBuffer(self.textTags)
        deserialization = self.tmpBuffer.register_deserialize_tagset()
        self.tmpBuffer.deserialize(self.tmpBuffer, deserialization, self.tmpBuffer.get_start_iter(), self.textBuffer.serialize(self.textBuffer, "application/x-gtk-text-buffer-rich-text", self.textBuffer.get_start_iter(), self.textBuffer.get_end_iter()))
        self.boldLock = False
        self.italLock = False
        self.undlLock = False
        self.beginMark = self.tmpBuffer.create_mark(None, self.tmpBuffer.get_start_iter(), False)
        self.endMark = self.tmpBuffer.create_mark(None, self.tmpBuffer.get_start_iter(), True)
        apply_tag(self)
        tmpIter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
        tmpVar = tmpIter.forward_to_tag_toggle(None)
        while tmpVar:
            self.beginMark = self.tmpBuffer.create_mark(None, tmpIter, False)
            self.endMark = self.tmpBuffer.create_mark(None, tmpIter, True)
            apply_tag(self)
            tmpIter = self.tmpBuffer.get_iter_at_mark(self.endMark)
            tmpVar = tmpIter.forward_to_tag_toggle(None)
        text = self.tmpBuffer.get_text(self.tmpBuffer.get_start_iter(), self.tmpBuffer.get_end_iter())
        del(self.beginMark, self.endMark, self.boldLock, self.italLock, self.undlLock, self.tmpBuffer)
        return text


    def textCopyTo(self, event, data=None):
        def apply_tag(self):
            iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
            if iter.begins_tag(self.boldTag) and not self.boldLock:
                self.tmpBuffer.insert(iter, '[b]')
                self.boldLock = True
            iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
            if iter.begins_tag(self.italTag) and not self.italLock:
                self.tmpBuffer.insert(iter, '[i]')
                self.italLock = True
            iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
            if iter.begins_tag(self.undlTag) and not self.undlLock:
                self.tmpBuffer.insert(iter, '[u]')<commit_msg>Added save support for size; size implementation now complete.<commit_after>#!/usr/bin/env python
# Thanks a lot to nemo_ on irc.gnome.org for help on this and <NAME> for undostack!

import pygtk, gtk, os, re, sys, gobject, copy, pango, ast, tempfile, enchant, undostack
pygtk.require('2.0')

if not os.path.exists(os.path.join(os.path.expanduser('~'), '.config', 'smartte')):
    os.mkdir(os.path.join(os.path.expanduser('~'), '.config', 'smartte'))



class MainWindow(object):
    class BindedTextView(gtk.TextView):
        __gsignals__ = dict(
            keybinding = (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION,
                None,
                (str,))
        )
    gobject.type_register(BindedTextView)
    gtk.binding_entry_add_signal(BindedTextView, gtk.keysyms.C, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, 'keybinding', str, 'ctrl+shift+c')
    gtk.binding_entry_add_signal(BindedTextView, gtk.keysyms.X, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, 'keybinding', str, 'ctrl+shift+x')
    gtk.binding_entry_add_signal(BindedTextView, gtk.keysyms.V, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, 'keybinding', str, 'ctrl+shift+v')


    def keyBindings(self, widget, keyCombo):
        print keyCombo
        if keyCombo == 'ctrl+shift+c':
            self.textCopyTo()
        elif keyCombo == 'ctrl+shift+x':
            self.textConvertFrom(widget)
            outputStart, outputEnd = self.textBuffer.get_selection_bounds()
            self.textBuffer.delete(outputStart, outputEnd)


    def newFile(self, widget, data=None):
        self.textBuffer.set_text('')
        del self.filename


    def genFileFilters(self, fileSel):
        filter = gtk.FileFilter()
        filter.set_name('All Files')
        filter.add_pattern('*')
        fileSel.add_filter(filter)
        filter = gtk.FileFilter()
        filter.set_name('Plain Text+BBCode')
        filter.add_mime_type('text/plain')
        filter.add_pattern('*.txt')
        fileSel.add_filter(filter)


    def openFile(self, widget, data=None):
        fileSel =  gtk.FileChooserDialog(title='Open File', action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        self.genFileFilters(fileSel)
        response = fileSel.run()
        if response == gtk.RESPONSE_OK:
            self.openFileCli(fileSel.get_filename())
            fileSel.destroy()
        elif response == gtk.RESPONSE_CANCEL:
            fileSel.destroy()


    def openFileCli(self, filename):
        self.filename = filename
        File = open(self.filename, 'r')
        tmpFileData = File.read()
        File.close()
        firstLine = tmpFileData[:tmpFileData.find('\n')+1]
        tmpReg = re.compile(r'{*}\n')
        if not tmpReg.search(firstLine) == None:
            self.docSettings = ast.literal_eval(firstLine[:-1])
            fileData = tmpFileData[tmpFileData.find('\n')+1:]
            self.textConvertFrom(fileData)
            if not self.docSettings['ignoreList'] == []:
                for begin, end in self.docSettings['ignoreList']:
                    self.textBuffer.apply_tag_by_name('ignore', self.textBuffer.get_iter_at_offset(begin), self.textBuffer.get_iter_at_offset(end))
            del(self.docSettings['ignoreList'])
            for word in self.docSettings['docDict']:
                self.dict.add(word)
            if self.docSettings['justStyle'] == 'left':
                self.justLeftButton.set_active(True)
            elif self.docSettings['justStyle'] == 'center':
                self.justCenterButton.set_active(True)
            elif self.docSettings['justStyle'] == 'right':
                self.justRightButton.set_active(True)
            elif self.docSettings['justStyle'] == 'fill':
                self.justFillButton.set_active(True)
        else:
            fileData = tmpFileData
            self.textConvertFrom(fileData)
        self.openCheckSpelling()
        self.textBuffer.set_modified(False)
        self.curPos = self.textBuffer.create_mark(None, self.textBuffer.get_iter_at_mark(self.textBuffer.get_insert()))
        self.curOldPos = self.textBuffer.create_mark(None, self.textBuffer.get_iter_at_mark(self.textBuffer.get_insert()))


    def writeFile(self):
        docText = self.textConvertTo()
        tmpSettings = copy.deepcopy(self.docSettings)
        tmpSettings['ignoreList'] = []
        if tmpSettings['saveIgnore']:
            tmpIter = self.textBuffer.get_start_iter()
            if tmpIter.begins_tag(self.ignoreTag):
                beginIter = self.textBuffer.get_iter_at_offset(tmpIter.get_offset())
            else:
                tmpIter.forward_to_tag_toggle(self.ignoreTag)
                beginIter = self.textBuffer.get_iter_at_offset(tmpIter.get_offset())
            tmpIter.forward_to_tag_toggle(self.ignoreTag)
            endIter = tmpIter
            tmpSettings['ignoreList'].append((beginIter.get_offset(), endIter.get_offset()))
            tmpVar = tmpIter.forward_to_tag_toggle(self.ignoreTag)
            while tmpVar:
                beginIter = self.textBuffer.get_iter_at_offset(tmpIter.get_offset())
                tmpIter.forward_to_tag_toggle(self.ignoreTag)
                endIter = tmpIter
                tmpSettings['ignoreList'].append((beginIter.get_offset(), endIter.get_offset()))
                tmpVar = tmpIter.forward_to_tag_toggle(self.ignoreTag)
        finalDoc = str(tmpSettings) + '\n' + docText
        File = open(self.filename, 'w')
        File.write(finalDoc)
        File.close()
        self.textBuffer.set_modified(False)


    def saveAsFile(self, widget, data=None):
        fileSel =  gtk.FileChooserDialog(title='Save File', action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK))
        self.genFileFilters(fileSel)
        saveIgnore = gtk.CheckButton('Save Ignore list with file?')
        saveIgnore.set_active(True)
        saveIgnore.set_tooltip_text('If you choose not to save the list, then you will have to remark them again when you reopen the file.')
        saveIgnore.show()
        fileSel.set_extra_widget(saveIgnore)
        response = fileSel.run()
        if response == gtk.RESPONSE_OK:
            self.filename = fileSel.get_filename()
            self.docSettings['saveIgnore'] = saveIgnore.get_active()
            if os.path.exists(self.filename):
                checkDialog = gtk.MessageDialog(fileSel,gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_NONE, 'The file ' + os.path.basename(self.filename) + ' already exists, are you sure you want to overwrite it?')
                checkDialog.add_button(gtk.STOCK_NO, gtk.RESPONSE_NO)
                checkDialog.add_button(gtk.STOCK_YES, gtk.RESPONSE_YES)
                checkResponse = checkDialog.run()
                if checkResponse == gtk.RESPONSE_YES:
                    fileSel.destroy()
                    checkDialog.destroy()
                    self.writeFile()
                elif checkResponse == gtk.RESPONSE_NO:
                    fileSel.destroy()
                    checkDialog.destroy()
            else:
                fileSel.destroy()
                self.writeFile()
        elif response == gtk.RESPONSE_CANCEL:
            fileSel.destroy()


    def saveFile(self, widget, data=None):
        try: self.filename
        except AttributeError:
            self.saveAsFile(widget)
        else:
            self.writeFile()


    def textConvertTo(self, pos=0):
        def apply_tag(self):
            iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
            if iter.begins_tag(self.boldTag) and not self.boldLock:
                self.tmpBuffer.insert(iter, '[b]')
                self.boldLock = True
            iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
            if iter.begins_tag(self.italTag) and not self.italLock:
                self.tmpBuffer.insert(iter, '[i]')
                self.italLock = True
            iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
            if iter.begins_tag(self.undlTag) and not self.undlLock:
                self.tmpBuffer.insert(iter, '[u]')
                self.undlLock = True
            iter = self.tmpBuffer.get_iter_at_mark(self.endMark)
            if iter.ends_tag(self.boldTag) and self.boldLock:
                self.tmpBuffer.insert(iter, '[/b]')
                self.boldLock = False
            iter = self.tmpBuffer.get_iter_at_mark(self.endMark)
            if iter.ends_tag(self.italTag) and self.italLock:
                self.tmpBuffer.insert(iter, '[/i]')
                self.italLock = False
            iter = self.tmpBuffer.get_iter_at_mark(self.endMark)
            if iter.ends_tag(self.undlTag) and self.undlLock:
                self.tmpBuffer.insert(iter, '[/u]')
                self.undlLock = False
            for tagName in self.sizes:
                tag = self.sizes[tagName]
                iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
                if iter.begins_tag(tag) and not self.sizeLock[tagName]:
                    self.sizeLock[tagName] = True
                    if tag.get_property('size-set'):
                        self.tmpBuffer.insert(iter, '[size='+str(int(tag.get_property('size-points')))+'px]')
                    elif tag.get_property('scale-set'):
                        self.tmpBuffer.insert(iter, '[size='+str(int(tag.get_property('scale')))+']')
                iter = self.tmpBuffer.get_iter_at_mark(self.endMark)
                if iter.ends_tag(tag) and self.sizeLock[tagName]:
                    self.sizeLock[tagName] = False
                    self.tmpBuffer.insert(iter, '[/size]')
        self.tmpBuffer = gtk.TextBuffer(self.textTags)
        deserialization = self.tmpBuffer.register_deserialize_tagset()
        self.tmpBuffer.deserialize(self.tmpBuffer, deserialization, self.tmpBuffer.get_start_iter(), self.textBuffer.serialize(self.textBuffer, "application/x-gtk-text-buffer-rich-text", self.textBuffer.get_start_iter(), self.textBuffer.get_end_iter()))
        self.boldLock = False
        self.italLock = False
        self.undlLock = False
        self.sizeLock = {}
        for tagName in self.sizes:
            self.sizeLock[tagName] = False
        self.beginMark = self.tmpBuffer.create_mark(None, self.tmpBuffer.get_start_iter(), False)
        self.endMark = self.tmpBuffer.create_mark(None, self.tmpBuffer.get_start_iter(), True)
        apply_tag(self)
        tmpIter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
        tmpVar = tmpIter.forward_to_tag_toggle(None)
        while tmpVar:
            self.beginMark = self.tmpBuffer.create_mark(None, tmpIter, False)
            self.endMark = self.tmpBuffer.create_mark(None, tmpIter, True)
            apply_tag(self)
            tmpIter = self.tmpBuffer.get_iter_at_mark(self.endMark)
            tmpVar = tmpIter.forward_to_tag_toggle(None)
        text = self.tmpBuffer.get_text(self.tmpBuffer.get_start_iter(), self.tmpBuffer.get_end_iter())
        del(self.beginMark, self.endMark, self.boldLock, self.italLock, self.undlLock, self.tmpBuffer)
        return text


    def textCopyTo(self, event, data=None):
        def apply_tag(self):
            iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
            if iter.begins_tag(self.boldTag) and not self.boldLock:
                self.tmpBuffer.insert(iter, '[b]')
                self.boldLock = True
            iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
            if iter.begins_tag(self.italTag) and not self.italLock:
                self.tmpBuffer.insert(iter, '[i]')
                self.italLock = True
            iter = self.tmpBuffer.get_iter_at_mark(self.beginMark)
            if iter.begins_tag(self.undlTag) and not self.undlLock:
                self.tmpBuffer.insert(iter, '[u]')
{'fraction_non_alphanumeric': 0.11239662150272743, 'fraction_numerical': 0.0005278901988386416, 'mean_word_length': 2.4417865253595763, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1936415', 'n_tokens_mistral': 7190, 'n_tokens_neox': 6945, 'n_words': 1089}