basic formating

webkit2png
somas95 2018-07-26 18:38:57 +02:00
parent fd7fd701dd
commit a48b12d962
5 changed files with 277 additions and 282 deletions

View File

@ -15,8 +15,8 @@
### END LICENSE
import re
from gi.repository import Gtk # pylint: disable=E0611
from gi.repository import Pango # pylint: disable=E0611
from gi.repository import Gtk
from gi.repository import Pango
class MarkupBuffer():
@ -24,64 +24,56 @@ class MarkupBuffer():
def __init__(self, Parent, TextBuffer, base_leftmargin):
self.multiplier = 10
self.parent = Parent
self.TextBuffer = TextBuffer
self.text_buffer = TextBuffer
# Styles
self.italic = self.TextBuffer.create_tag("italic",
style=Pango.Style.ITALIC)
self.italic = self.text_buffer.create_tag("italic",
style=Pango.Style.ITALIC)
self.emph = self.TextBuffer.create_tag("emph",
weight=Pango.Weight.BOLD,
style=Pango.Style.NORMAL)
self.emph = self.text_buffer.create_tag("emph",
weight=Pango.Weight.BOLD,
style=Pango.Style.NORMAL)
self.bolditalic = self.TextBuffer.create_tag("bolditalic",
weight=Pango.Weight.BOLD,
style=Pango.Style.ITALIC)
self.bolditalic = self.text_buffer.create_tag("bolditalic",
weight=Pango.Weight.BOLD,
style=Pango.Style.ITALIC)
self.headline_two = self.TextBuffer.create_tag("headline_two",
weight=Pango.Weight.BOLD,
style=Pango.Style.NORMAL)
self.headline_two = self.text_buffer.create_tag("headline_two",
weight=Pango.Weight.BOLD,
style=Pango.Style.NORMAL)
self.normal_indent = self.TextBuffer.create_tag('normal_indent', indent=100)
self.normal_indent = self.text_buffer.create_tag('normal_indent', indent=100)
self.green_text = self.TextBuffer.create_tag(
"greentext",
foreground="#00364C"
)
self.green_text = self.text_buffer.create_tag("greentext",
foreground="#00364C")
self.grayfont = self.TextBuffer.create_tag('graytag',
foreground="gray")
self.grayfont = self.text_buffer.create_tag('graytag',
foreground="gray")
self.blackfont = self.TextBuffer.create_tag('blacktag',
foreground="#222")
self.blackfont = self.text_buffer.create_tag('blacktag',
foreground="#222")
self.underline = self.TextBuffer.create_tag(
"underline",
underline=Pango.Underline.SINGLE
)
self.underline = self.text_buffer.create_tag("underline",
underline=Pango.Underline.SINGLE)
self.underline.set_property('weight', Pango.Weight.BOLD)
self.strikethrough = self.TextBuffer.create_tag(
"strikethrough",
strikethrough=True
)
self.strikethrough = self.text_buffer.create_tag("strikethrough",
strikethrough=True)
self.centertext = self.TextBuffer.create_tag(
"centertext",
justification=Gtk.Justification.CENTER
)
self.centertext = self.text_buffer.create_tag("centertext",
justification=Gtk.Justification.CENTER)
self.TextBuffer.apply_tag(
self.text_buffer.apply_tag(
self.normal_indent,
self.TextBuffer.get_start_iter(),
self.TextBuffer.get_end_iter()
self.text_buffer.get_start_iter(),
self.text_buffer.get_end_iter()
)
self.rev_leftmargin = []
for i in range(0, 6):
name = "rev_marg_indent_left" + str(i)
self.rev_leftmargin.append(self.TextBuffer.create_tag(name))
self.rev_leftmargin.append(self.text_buffer.create_tag(name))
self.rev_leftmargin[i].set_property("left-margin", 90 - 10 * (i + 1))
self.rev_leftmargin[i].set_property("indent", - 10 * (i + 1) - 10)
#self.leftmargin[i].set_property("background", "gray")
@ -90,7 +82,7 @@ class MarkupBuffer():
for i in range(0, 6):
name = "marg_indent_left" + str(i)
self.leftmargin.append(self.TextBuffer.create_tag(name))
self.leftmargin.append(self.text_buffer.create_tag(name))
self.leftmargin[i].set_property("left-margin", base_leftmargin + 10 + 10 * (i + 1))
self.leftmargin[i].set_property("indent", - 10 * (i + 1) - 10)
@ -98,10 +90,10 @@ class MarkupBuffer():
for i in range(0, 15):
name = "indent_left" + str(i)
self.leftindent.append(self.TextBuffer.create_tag(name))
self.leftindent.append(self.text_buffer.create_tag(name))
self.leftindent[i].set_property("indent", - 10 * (i + 1) - 20)
self.table_env = self.TextBuffer.create_tag('table_env')
self.table_env = self.text_buffer.create_tag('table_env')
self.table_env.set_property('wrap-mode', Gtk.WrapMode.NONE)
# self.table_env.set_property('font', 'Ubuntu Mono 13px')
self.table_env.set_property('pixels-above-lines', 0)
@ -127,7 +119,7 @@ class MarkupBuffer():
}
def markup_buffer(self, mode=0):
buf = self.TextBuffer
buf = self.text_buffer
# Test for shifting first line
# bbs = buf.get_start_iter()
@ -154,134 +146,136 @@ class MarkupBuffer():
text = buf.get_slice(context_start, context_end, False)
self.TextBuffer.remove_tag(self.italic, context_start, context_end)
self.text_buffer.remove_tag(self.italic, context_start, context_end)
matches = re.finditer(self.regex["ITALIC"], text)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
self.TextBuffer.apply_tag(self.italic, startIter, endIter)
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
self.text_buffer.apply_tag(self.italic, start_iter, end_iter)
self.TextBuffer.remove_tag(self.emph, context_start, context_end)
self.text_buffer.remove_tag(self.emph, context_start, context_end)
matches = re.finditer(self.regex["STRONG"], text)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
self.TextBuffer.apply_tag(self.emph, startIter, endIter)
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
self.text_buffer.apply_tag(self.emph, start_iter, end_iter)
matches = re.finditer(self.regex["STRONGITALIC"], text)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
self.TextBuffer.apply_tag(self.bolditalic, startIter, endIter)
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
self.text_buffer.apply_tag(self.bolditalic, start_iter, end_iter)
self.TextBuffer.remove_tag(self.strikethrough, context_start, context_end)
self.text_buffer.remove_tag(self.strikethrough, context_start, context_end)
matches = re.finditer(self.regex["STRIKETHROUGH"], text)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
self.TextBuffer.apply_tag(self.strikethrough, startIter, endIter)
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
self.text_buffer.apply_tag(self.strikethrough, start_iter, end_iter)
self.TextBuffer.remove_tag(self.green_text, context_start, context_end)
self.text_buffer.remove_tag(self.green_text, context_start, context_end)
matches = re.finditer(self.regex["MATH"], text)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
self.TextBuffer.apply_tag(self.green_text, startIter, endIter)
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
self.text_buffer.apply_tag(self.green_text, start_iter, end_iter)
for margin in self.rev_leftmargin:
self.TextBuffer.remove_tag(margin, context_start, context_end)
self.text_buffer.remove_tag(margin, context_start, context_end)
matches = re.finditer(self.regex["LIST"], text)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
self.TextBuffer.apply_tag(self.rev_leftmargin[0], startIter, endIter)
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
self.text_buffer.apply_tag(self.rev_leftmargin[0], start_iter, end_iter)
matches = re.finditer(self.regex["NUMERICLIST"], text)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
index = len(match.group(1)) - 1
if index < len(self.rev_leftmargin):
margin = self.rev_leftmargin[index]
self.TextBuffer.apply_tag(margin, startIter, endIter)
self.text_buffer.apply_tag(margin, start_iter, end_iter)
matches = re.finditer(self.regex["BLOCKQUOTE"], text)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
index = len(match.group(1)) - 2
if index < len(self.leftmargin):
self.TextBuffer.apply_tag(self.leftmargin[index], startIter, endIter)
self.text_buffer.apply_tag(self.leftmargin[index], start_iter, end_iter)
for leftindent in self.leftindent:
self.TextBuffer.remove_tag(leftindent, context_start, context_end)
self.text_buffer.remove_tag(leftindent, context_start, context_end)
matches = re.finditer(self.regex["INDENTEDLIST"], text)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
index = (len(match.group(1)) - 1) * 2 + len(match.group(2))
if index < len(self.leftindent):
self.TextBuffer.apply_tag(self.leftindent[index], startIter, endIter)
self.text_buffer.apply_tag(self.leftindent[index], start_iter, end_iter)
matches = re.finditer(self.regex["HEADINDICATOR"], text)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
index = len(match.group(1)) - 1
if index < len(self.rev_leftmargin):
margin = self.rev_leftmargin[index]
self.TextBuffer.apply_tag(margin, startIter, endIter)
self.text_buffer.apply_tag(margin, start_iter, end_iter)
matches = re.finditer(self.regex["HORIZONTALRULE"], text)
rulecontext = context_start.copy()
rulecontext.forward_lines(3)
self.TextBuffer.remove_tag(self.centertext, rulecontext, context_end)
self.text_buffer.remove_tag(self.centertext, rulecontext, context_end)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
startIter.forward_chars(2)
endIter = buf.get_iter_at_offset(context_offset + match.end())
self.TextBuffer.apply_tag(self.centertext, startIter, endIter)
start_iter = buf.get_iter_at_offset(context_offset + match.start())
start_iter.forward_chars(2)
end_iter = buf.get_iter_at_offset(context_offset + match.end())
self.text_buffer.apply_tag(self.centertext, start_iter, end_iter)
matches = re.finditer(self.regex["HEADLINE"], text)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
self.TextBuffer.apply_tag(self.emph, startIter, endIter)
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
self.text_buffer.apply_tag(self.emph, start_iter, end_iter)
matches = re.finditer(self.regex["HEADLINE_TWO"], text)
self.TextBuffer.remove_tag(self.headline_two, rulecontext, context_end)
self.text_buffer.remove_tag(self.headline_two, rulecontext, context_end)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
self.TextBuffer.apply_tag(self.headline_two, startIter, endIter)
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
self.text_buffer.apply_tag(self.headline_two, start_iter, end_iter)
matches = re.finditer(self.regex["TABLE"], text)
for match in matches:
startIter = buf.get_iter_at_offset(context_offset + match.start())
endIter = buf.get_iter_at_offset(context_offset + match.end())
self.TextBuffer.apply_tag(self.table_env, startIter, endIter)
start_iter = buf.get_iter_at_offset(context_offset + match.start())
end_iter = buf.get_iter_at_offset(context_offset + match.end())
self.text_buffer.apply_tag(self.table_env, start_iter, end_iter)
if self.parent.focusmode:
self.focusmode_highlight()
def focusmode_highlight(self):
self.TextBuffer.apply_tag(self.grayfont,
self.TextBuffer.get_start_iter(),
self.TextBuffer.get_end_iter())
self.text_buffer.apply_tag(
self.grayfont,
self.text_buffer.get_start_iter(),
self.text_buffer.get_end_iter())
self.TextBuffer.remove_tag(self.blackfont,
self.TextBuffer.get_start_iter(),
self.TextBuffer.get_end_iter())
self.text_buffer.remove_tag(
self.blackfont,
self.text_buffer.get_start_iter(),
self.text_buffer.get_end_iter())
cursor = self.TextBuffer.get_mark("insert")
cursor_iter = self.TextBuffer.get_iter_at_mark(cursor)
cursor = self.text_buffer.get_mark("insert")
cursor_iter = self.text_buffer.get_iter_at_mark(cursor)
end_sentence = cursor_iter.copy()
end_sentence.forward_sentence_end()
@ -297,7 +291,8 @@ class MarkupBuffer():
start_sentence = cursor_iter.copy()
start_sentence.backward_sentence_start()
self.TextBuffer.apply_tag(self.blackfont,
self.text_buffer.apply_tag(
self.blackfont,
start_sentence, end_sentence)
def set_multiplier(self, multiplier):
@ -306,7 +301,7 @@ class MarkupBuffer():
def recalculate(self, lm):
multiplier = self.multiplier
for i in range(0, 6):
new_margin = (lm - multiplier) - multiplier * (i + 1)
new_margin = (lm - multiplier) - multiplier * (i + 1)
self.rev_leftmargin[i].set_property("left-margin", 0 if new_margin < 0 else new_margin)
self.rev_leftmargin[i].set_property("indent", - multiplier * (i + 1) - multiplier)

View File

@ -1,32 +1,30 @@
# UberwriterAutoCorrect
# The Uberwriter Auto Correct is a auto correction
# The Uberwriter Auto Correct is a auto correction
# mechanism to prevent stupid typos
# import presage
from gi.repository import Gtk, Gdk
import uberwriter_lib.pressagio as pressagio
import enchant
# d = enchant.Dict("de_DE")
import re
import uberwriter_lib.pressagio.predictor
import uberwriter_lib.pressagio.tokenizer
import uberwriter_lib.pressagio.dbconnector
import uberwriter_lib.pressagio.context_tracker
import uberwriter_lib.pressagio.callback
import os
import pickle
import configparser
import xml.etree.ElementTree as ET
import pickle
from Levenshtein import distance
from gi.repository import Gtk, Gdk
import enchant
from uberwriter_lib import pressagio
# import uberwriter_lib.pressagio.predictor
# import uberwriter_lib.pressagio.tokenizer
# import uberwriter_lib.pressagio.dbconnector
# import uberwriter_lib.pressagio.context_tracker
# import uberwriter_lib.pressagio.callback
# from Levenshtein import distance
import configparser
from uberwriter_lib.helpers import get_media_path
# Define and create PresageCallback object
class PressagioCallback(pressagio.callback.Callback):
def __init__(self, buffer):
super().__init__()
@ -34,18 +32,18 @@ class PressagioCallback(pressagio.callback.Callback):
def past_stream(self):
return self.buffer
def future_stream(self):
return ''
class UberwriterAutoCorrect:
def show_bubble(self, iter, suggestion):
def show_bubble(self, iterator, suggestion):
self.suggestion = suggestion
if self.bubble:
self.bubble_label.set_text(suggestion)
else:
pos = self.TextView.get_iter_location(iter)
pos = self.TextView.get_iter_location(iterator)
pos_adjusted = self.TextView.buffer_to_window_coords(
Gtk.TextWindowType.TEXT, pos.x, pos.y + pos.height)
self.bubble_eventbox = Gtk.EventBox.new()
@ -54,8 +52,9 @@ class UberwriterAutoCorrect:
self.bubble_eventbox.add(self.bubble)
self.bubble_eventbox.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
self.bubble_eventbox.connect("button_press_event", self.clicked_bubble)
self.TextView.add_child_in_window(self.bubble_eventbox,
Gtk.TextWindowType.TEXT, pos_adjusted[0], pos_adjusted[1])
self.TextView.add_child_in_window(self.bubble_eventbox,
Gtk.TextWindowType.TEXT,
pos_adjusted[0], pos_adjusted[1])
self.bubble_label = Gtk.Label.new(suggestion)
@ -68,10 +67,10 @@ class UberwriterAutoCorrect:
self.bubble.attach(self.bubble_close_eventbox, 1, 0, 1, 1)
self.bubble_eventbox.show_all()
def clicked_bubble(self, widget, data=None):
def clicked_bubble(self, _widget, _data=None):
self.accept_suggestion()
def clicked_close(self, widget, data=None):
def clicked_close(self, _widget, _data=None):
self.destroy_bubble()
def suggest(self, stump, context):
@ -85,7 +84,7 @@ class UberwriterAutoCorrect:
if self.use_pressagio:
predictions = self.prsgio.predict(6, None)
prediction = None
if not len(predictions):
if not predictions:
if self.enchant_dict.check(stump):
self.destroy_bubble()
return
@ -93,45 +92,46 @@ class UberwriterAutoCorrect:
suggestions_map = []
for suggestion in predictions:
if suggestion in self.frequency_dict:
suggestions_map.append({'suggestion': suggestion, 'freq': self.frequency_dict[suggestion]})
suggestions_map.append({'suggestion': suggestion,
'freq': self.frequency_dict[suggestion]})
else:
suggestions_map.append({'suggestion': suggestion, 'freq': 0})
suggestions_map.sort(key=lambda x: x['freq'])
suggestions_map.reverse()
prediction = suggestions_map[0]
print(predictions)
prediction = predictions[0]
else:
else:
prediction = predictions[0].word
anchor_iter = self.buffer.get_iter_at_mark(self.buffer.get_insert())
anchor_iter.backward_visible_word_start()
if len(stump) >= 1:
self.show_bubble(anchor_iter, prediction)
def destroy_bubble(self, *args):
def destroy_bubble(self, *_args):
if not self.bubble:
return
self.bubble.destroy()
self.bubble = None
self.suggestion = ''
def get_frequency_dict(self, language):
def get_frequency_dict(self, _language):
self.frequency_dict = {}
pp_pickled = get_media_path("frequency_dict_" + self.language + ".pickle")
if pp_pickled and os.path.isfile(pp_pickled):
f = open(pp_pickled, 'rb')
self.frequency_dict = pickle.load(f)
f.close()
frequency_file = open(pp_pickled, 'rb')
self.frequency_dict = pickle.load(frequency_file)
frequency_file.close()
else:
pp = get_media_path('wordlists/en_us_wordlist.xml')
frequencies = ET.parse(pp)
root = frequencies.getroot()
for child in root:
self.frequency_dict[child.text] = int(child.attrib['f'])
f = open('pickled_dict', 'wb+')
pickle.dump(self.frequency_dict, f)
f.close()
frequency_file = open('pickled_dict', 'wb+')
pickle.dump(self.frequency_dict, frequency_file)
frequency_file.close()
def accept_suggestion(self, append=""):
print("called")
@ -142,19 +142,20 @@ class UberwriterAutoCorrect:
self.buffer.insert_at_cursor(self.suggestion + append)
self.destroy_bubble()
def key_pressed(self, widget, event):
def key_pressed(self, _widget, event):
if not self.bubble:
return False
if event.keyval in [Gdk.KEY_Escape, Gdk.KEY_BackSpace]:
self.destroy_bubble()
return False
def text_insert(self, buffer, location,
text, len, data=None):
def text_insert(self, buffer, location,
text, _length, _data=None):
# check if at end of a word
# if yes, check if suggestion available
# then display suggetion
if self.suggestion and text in [' ', '\t', '\n', '.', '?', '!', ',', ';', '\'', '"', ')', ':']:
if self.suggestion and text in [' ', '\t', '\n', '.', '?', '!',
',', ';', '\'', '"', ')', ':']:
self.accept_suggestion(append=text)
location.assign(self.buffer.get_iter_at_mark(self.buffer.get_insert()))
elif location.ends_word():
@ -174,25 +175,25 @@ class UberwriterAutoCorrect:
print("Language changed to: %s" % language)
# handle 2 char cases e.g. "en"
if(len(language) == 2):
if len(language) == 2:
if "en":
language = "en_US"
if self.language == language:
return
else:
self.language = language
print("Language changing")
config_file = get_media_path("pressagio_config.ini")
pres_config = configparser.ConfigParser()
pres_config.read(config_file)
pres_config.set("Database", "database", get_media_path("corpora/" + self.language + ".sqlite"))
self.context_tracker = pressagio.context_tracker.ContextTracker(
pres_config, self.predictor_registry, self.callback)
self.prsgio = self.predictor_registry[0]
self.language = language
print("Language changing")
config_file = get_media_path("pressagio_config.ini")
pres_config = configparser.ConfigParser()
pres_config.read(config_file)
pres_config.set("Database", "database",
get_media_path("corpora/" + self.language + ".sqlite"))
self.context_tracker = pressagio.context_tracker.ContextTracker(
pres_config, self.predictor_registry, self.callback)
self.prsgio = self.predictor_registry[0]
self.enchant_dict = enchant.Dict(self.language)
self.enchant_dict = enchant.Dict(self.language)
def __init__(self, textview, textbuffer):
self.TextView = textview
@ -206,15 +207,16 @@ class UberwriterAutoCorrect:
self.frequency_dict = {}
self.get_frequency_dict(self.language)
self.enchant_dict = enchant.Dict(self.language)
self.use_pressagio = False
config_file = get_media_path("pressagio_config.ini")
pres_config = configparser.ConfigParser()
pres_config.read(config_file)
pres_config.set("Database", "database", get_media_path("corpora/" + self.language + ".sqlite"))
pres_config.set("Database", "database",
get_media_path("corpora/" + self.language + ".sqlite"))
self.callback = PressagioCallback("")
self.predictor_registry = pressagio.predictor.PredictorRegistry(pres_config)
self.context_tracker = pressagio.context_tracker.ContextTracker(
pres_config, self.predictor_registry, self.callback)
self.prsgio = self.predictor_registry[0]
self.prsgio = self.predictor_registry[0]

View File

@ -14,25 +14,24 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
### END LICENSE
import os, re
import subprocess
from gi.repository import Gtk, Gdk
import time
import re
import logging
from gi.repository import Gdk
# from plugins import plugins
import logging
logger = logging.getLogger('uberwriter')
LOGGER = logging.getLogger('uberwriter')
class UberwriterSearchAndReplace():
"""
Adds (regex) search and replace functionality to
Adds (regex) search and replace functionality to
uberwriter
"""
def __init__(self, parentwindow):
self.parentwindow = parentwindow
self.box = parentwindow.builder.get_object("searchbar_placeholder")
self.box.set_reveal_child(False)
self.searchbar=parentwindow.builder.get_object("searchbar")
self.searchbar = parentwindow.builder.get_object("searchbar")
self.searchentry = parentwindow.builder.get_object("searchentrybox")
self.searchentry.connect('changed', self.search)
self.searchentry.connect('activate', self.scrolltonext)
@ -41,14 +40,14 @@ class UberwriterSearchAndReplace():
self.open_replace_button = parentwindow.builder.get_object("replace")
self.open_replace_button.connect("toggled", self.toggle_replace)
self.textbuffer = parentwindow.TextBuffer
self.texteditor = parentwindow.TextEditor
self.textbuffer = parentwindow.text_buffer
self.texteditor = parentwindow.text_editor
self.nextbutton = parentwindow.builder.get_object("next_result")
self.prevbutton = parentwindow.builder.get_object("previous_result")
self.regexbutton = parentwindow.builder.get_object("regex")
self.casesensitivebutton = parentwindow.builder.get_object("case_sensitive")
self.replacebox = parentwindow.builder.get_object("replace_placeholder")
self.replacebox.set_reveal_child(False)
self.replace_one_button = parentwindow.builder.get_object("replace_one")
@ -64,36 +63,44 @@ class UberwriterSearchAndReplace():
self.regexbutton.connect('toggled', self.search)
self.casesensitivebutton.connect('toggled', self.search)
self.highlight = self.textbuffer.create_tag('search_highlight',
background="yellow")
background="yellow")
self.texteditor.connect("focus-in-event", self.focused_texteditor)
def toggle_replace(self, widget, data=None):
def toggle_replace(self, widget, _data=None):
"""toggle the replace box
"""
if widget.get_active():
self.replacebox.set_reveal_child(True)
else:
else:
self.replacebox.set_reveal_child(False)
def key_pressed(self, widget, event, data=None):
# TODO: refactorize!
def key_pressed(self, _widget, event, _data=None):
"""hide the search and replace content box when ESC is pressed
"""
if event.keyval in [Gdk.KEY_Escape]:
self.hide()
def focused_texteditor(self, widget, data=None):
def focused_texteditor(self, _widget, _data=None):
"""hide the search and replace content box
"""
self.hide()
def toggle_search(self, widget=None, data=None):
def toggle_search(self, _widget=None, _data=None):
"""
show search box
"""
if self.box.get_reveal_child() == False or self.searchbar.get_search_mode() == False:
if self.box.get_reveal_child() is False or self.searchbar.get_search_mode() is False:
self.searchbar.set_search_mode(True)
self.box.set_reveal_child(True)
self.searchentry.grab_focus()
else:
self.hide()
self.open_replace_button.set_active(False)
def search(self, widget=None, data=None, scroll=True):
def search(self, _widget=None, _data=None, scroll=True):
searchtext = self.searchentry.get_text()
buf = self.textbuffer
context_start = buf.get_start_iter()
@ -110,34 +117,34 @@ class UberwriterSearchAndReplace():
# regex?
if not self.regexbutton.get_active():
searchtext = re.escape(searchtext)
matches = re.finditer(searchtext, text, flags)
self.matchiters = []
self.active = 0
for match in matches:
startIter = buf.get_iter_at_offset(match.start())
endIter = buf.get_iter_at_offset(match.end())
self.matchiters.append((startIter, endIter))
self.textbuffer.apply_tag(self.highlight, startIter, endIter)
for match in matches:
start_iter = buf.get_iter_at_offset(match.start())
end_iter = buf.get_iter_at_offset(match.end())
self.matchiters.append((start_iter, end_iter))
self.textbuffer.apply_tag(self.highlight, start_iter, end_iter)
if scroll:
self.scrollto(self.active)
logger.debug(searchtext)
LOGGER.debug(searchtext)
def scrolltonext(self, widget, data=None):
def scrolltonext(self, _widget, _data=None):
self.scrollto(self.active + 1)
def scrolltoprev(self, widget, data=None):
def scrolltoprev(self, _widget, _data=None):
self.scrollto(self.active - 1)
def scrollto(self, index):
if not len(self.matchiters):
if not self.matchiters:
return
if(index < len(self.matchiters)):
if index < len(self.matchiters):
self.active = index
else:
else:
self.active = 0
matchiter = self.matchiters[self.active]
self.texteditor.get_buffer().select_range(matchiter[0], matchiter[1])
@ -146,23 +153,23 @@ class UberwriterSearchAndReplace():
def hide(self):
self.replacebox.set_reveal_child(False)
self.box.set_reveal_child(False)
self.textbuffer.remove_tag(self.highlight,
self.textbuffer.get_start_iter(),
self.textbuffer.get_end_iter())
self.textbuffer.remove_tag(self.highlight,
self.textbuffer.get_start_iter(),
self.textbuffer.get_end_iter())
self.texteditor.grab_focus()
def replace_clicked(self, widget, data=None):
def replace_clicked(self, _widget, _data=None):
self.replace(self.active)
def replace_all(self, widget=None, data=None):
def replace_all(self, _widget=None, _data=None):
while self.matchiters:
match = self.matchiters[0]
self.textbuffer.delete(match[0], match[1])
self.textbuffer.insert(match[0], self.replaceentry.get_text())
self.search(scroll=False)
def replace(self, searchindex, inloop=False):
def replace(self, searchindex, _inloop=False):
match = self.matchiters[searchindex]
self.textbuffer.delete(match[0], match[1])
self.textbuffer.insert(match[0], self.replaceentry.get_text())
@ -170,4 +177,4 @@ class UberwriterSearchAndReplace():
self.search(scroll=False)
self.active = active
self.parentwindow.MarkupBuffer.markup_buffer()
self.scrollto(self.active)
self.scrollto(self.active)

View File

@ -1,19 +1,19 @@
### BEGIN LICENSE
# Copyright (C) 2012, Wolf Vollprecht <w.vollprecht@gmail.com>
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
### END LICENSE
"""Module for the TextView widgth wich encapsulates management of TextBuffer
and TextIter for common functionality, such as cut, copy, paste, undo, redo,
and TextIter for common functionality, such as cut, copy, paste, undo, redo,
and highlighting of text.
Using
@ -58,13 +58,13 @@ except:
import logging
logger = logging.getLogger('uberwriter')
LOGGER = logging.getLogger('uberwriter')
class UndoableInsert(object):
class UndoableInsert:
"""something that has been inserted into our textbuffer"""
def __init__(self, text_iter, text, length):
self.offset = text_iter.get_offset()
self.offset = text_iter.get_offset()
self.text = text
self.length = length
if self.length > 1 or self.text in ("\r", "\n", " "):
@ -73,7 +73,7 @@ class UndoableInsert(object):
self.mergeable = True
class UndoableDelete(object):
class UndoableDelete:
"""something that has ben deleted from our textbuffer"""
def __init__(self, text_buffer, start_iter, end_iter):
self.text = text_buffer.get_text(start_iter, end_iter, False)
@ -82,21 +82,15 @@ class UndoableDelete(object):
# need to find out if backspace or delete key has been used
# so we don't mess up during redo
insert_iter = text_buffer.get_iter_at_mark(text_buffer.get_insert())
if insert_iter.get_offset() <= self.start:
self.delete_key_used = True
else:
self.delete_key_used = False
if self.end - self.start > 1 or self.text in ("\r", "\n", " "):
self.mergeable = False
else:
self.mergeable = True
self.delete_key_used = bool(insert_iter.get_offset() <= self.start)
self.mergeable = not bool(self.end - self.start > 1
or self.text in ("\r", "\n", " "))
class TextEditor(Gtk.TextView):
"""TextEditor encapsulates management of TextBuffer and TextIter for
common functionality, such as cut, copy, paste, undo, redo, and
highlighting of text.
"""
__gsignals__ = {
@ -110,8 +104,9 @@ class TextEditor(Gtk.TextView):
'redo': (GObject.SIGNAL_ACTION, None, ())
}
def scroll_to_iter(self, iter, *args):
self.get_buffer().place_cursor(iter)
# TODO: delete this?
def scroll_to_iter(self, iterable, *args):
self.get_buffer().place_cursor(iterable)
def __init__(self):
"""
@ -131,7 +126,7 @@ class TextEditor(Gtk.TextView):
self.not_undoable_action = False
self.undo_in_progress = False
self.FormatShortcuts = FormatShortcuts(self.get_buffer(), self)
self.format_shortcuts = FormatShortcuts(self.get_buffer(), self)
self.connect('insert-italic', self.set_italic)
self.connect('insert-bold', self.set_bold)
@ -153,7 +148,7 @@ class TextEditor(Gtk.TextView):
This property is read/write.
"""
start_iter = self.get_buffer().get_iter_at_offset(0)
end_iter = self.get_buffer().get_iter_at_offset(-1)
end_iter = self.get_buffer().get_iter_at_offset(-1)
return self.get_buffer().get_text(start_iter, end_iter, False)
@property
@ -178,7 +173,7 @@ class TextEditor(Gtk.TextView):
"""
end_iter = self.get_buffer().get_iter_at_offset(-1)
end_iter = self.get_buffer().get_iter_at_offset(-1)
self.get_buffer().insert(end_iter, text)
def prepend(self, text):
@ -190,7 +185,7 @@ class TextEditor(Gtk.TextView):
"""
start_iter = self.get_buffer().get_iter_at_offset(0)
start_iter = self.get_buffer().get_iter_at_offset(0)
self.get_buffer().insert(start_iter, text)
insert_iter = self.get_buffer().get_iter_at_offset(len(text)-1)
self.get_buffer().place_cursor(insert_iter)
@ -213,7 +208,7 @@ class TextEditor(Gtk.TextView):
start_iter = self.get_buffer().get_iter_at_offset(0)
self.get_buffer().place_cursor(start_iter)
def cut(self, widget=None, data=None):
def cut(self, _widget=None, _data=None):
"""cut: cut currently selected text and put it on the clipboard.
This function can be called as a function, or assigned as a signal
handler.
@ -222,16 +217,14 @@ class TextEditor(Gtk.TextView):
self.get_buffer().cut_clipboard(self.clipboard, True)
def copy(self, widget=None, data=None):
def copy(self, _widget=None, _data=None):
"""copy: copy currently selected text to the clipboard.
This function can be called as a function, or assigned as a signal
handler.
This function can be called as a function, or assigned as a signal
handler.
"""
self.get_buffer().copy_clipboard(self.clipboard)
self.get_buffer().copy_clipboard(self.clipboard)
def paste(self, widget=None, data=None):
def paste(self, _widget=None, _data=None):
"""paste: Insert any text currently on the clipboard into the
buffer.
This function can be called as a function, or assigned as a signal
@ -239,9 +232,9 @@ class TextEditor(Gtk.TextView):
"""
self.get_buffer().paste_clipboard(self.clipboard,None,True)
self.get_buffer().paste_clipboard(self.clipboard, None, True)
def undo(self, widget=None, data=None):
def undo(self, _widget=None, _data=None):
"""undo inserts or deletions
undone actions are being moved to redo stack"""
if not self.undo_stack:
@ -270,7 +263,7 @@ class TextEditor(Gtk.TextView):
self.end_not_undoable_action()
self.undo_in_progress = False
def redo(self, widget=None, data=None):
def redo(self, _widget=None, _data=None):
"""redo inserts or deletions
redone actions are moved to undo stack"""
@ -296,7 +289,7 @@ class TextEditor(Gtk.TextView):
self.end_not_undoable_action()
self.undo_in_progress = False
def on_insert_text(self, textbuffer, text_iter, text, length):
def on_insert_text(self, _textbuffer, text_iter, text, _length):
"""
_on_insert: internal function to handle programatically inserted
text. Do not call directly.
@ -308,14 +301,14 @@ class TextEditor(Gtk.TextView):
can't merge if prev and cur are not mergeable in the first place
can't merge when user set the input bar somewhere else
can't merge across word boundaries"""
WHITESPACE = (' ', '\t')
whitespace = (' ', '\t')
if not cur.mergeable or not prev.mergeable:
return False
elif cur.offset != (prev.offset + prev.length):
if cur.offset != (prev.offset + prev.length):
return False
elif cur.text in WHITESPACE and not prev.text in WHITESPACE:
if cur.text in whitespace and not prev.text in whitespace:
return False
elif prev.text in WHITESPACE and not cur.text in WHITESPACE:
if prev.text in whitespace and not cur.text in whitespace:
return False
return True
@ -341,10 +334,9 @@ class TextEditor(Gtk.TextView):
else:
self.undo_stack.append(prev_insert)
self.undo_stack.append(undo_action)
def on_delete_range(self, text_buffer, start_iter, end_iter):
"""
On delete
"""On delete
"""
def can_be_merged(prev, cur):
"""see if we can merge multiple deletions here
@ -354,18 +346,18 @@ class TextEditor(Gtk.TextView):
can't merge if delete and backspace key were both used
can't merge across word boundaries"""
WHITESPACE = (' ', '\t')
whitespace = (' ', '\t')
if not cur.mergeable or not prev.mergeable:
return False
elif prev.delete_key_used != cur.delete_key_used:
if prev.delete_key_used != cur.delete_key_used:
return False
elif prev.start != cur.start and prev.start != cur.end:
if prev.start != cur.start and prev.start != cur.end:
return False
elif cur.text not in WHITESPACE and \
prev.text in WHITESPACE:
if cur.text not in whitespace and \
prev.text in whitespace:
return False
elif cur.text in WHITESPACE and \
prev.text not in WHITESPACE:
if cur.text in whitespace and \
prev.text not in whitespace:
return False
return True
@ -389,50 +381,50 @@ class TextEditor(Gtk.TextView):
prev_delete.end += (undo_action.end - undo_action.start)
else: # Backspace used
prev_delete.text = "%s%s" % (undo_action.text,
prev_delete.text)
prev_delete.text)
prev_delete.start = undo_action.start
self.undo_stack.append(prev_delete)
else:
self.undo_stack.append(prev_delete)
self.undo_stack.append(undo_action)
self.undo_stack.append(undo_action)
def begin_not_undoable_action(self):
"""don't record the next actions
toggles self.not_undoable_action"""
self.not_undoable_action = True
self.not_undoable_action = True
def end_not_undoable_action(self):
"""record next actions
toggles self.not_undoable_action"""
self.not_undoable_action = False
def set_italic(self, widget, data=None):
def set_italic(self, _widget, _data=None):
"""Ctrl + I"""
self.FormatShortcuts.italic()
self.format_shortcuts.italic()
def set_bold(self, widget, data=None):
def set_bold(self, _widget, _data=None):
"""Ctrl + Shift + D"""
self.FormatShortcuts.bold()
self.format_shortcuts.bold()
def set_strikeout(self, widget, data=None):
def set_strikeout(self, _widget, _data=None):
"""Ctrl + B"""
self.FormatShortcuts.strikeout()
self.format_shortcuts.strikeout()
def insert_horizontal_rule(self, widget, data=None):
def insert_horizontal_rule(self, _widget, _data=None):
"""Ctrl + R"""
self.FormatShortcuts.rule()
self.format_shortcuts.rule()
def insert_unordered_list_item(self, widget, data=None):
def insert_unordered_list_item(self, _widget, _data=None):
"""Ctrl + U"""
self.FormatShortcuts.unordered_list_item()
self.format_shortcuts.unordered_list_item()
def insert_ordered_list(self, widget, data=None):
def insert_ordered_list(self, _widget, _data=None):
"""CTRL + O"""
self.FormatShortcuts.ordered_list_item()
self.format_shortcuts.ordered_list_item()
def insert_heading(self, widget, data=None):
def insert_heading(self, _widget, _data=None):
"""CTRL + H"""
self.FormatShortcuts.heading()
self.format_shortcuts.heading()
class TestWindow(Gtk.Window):
@ -449,10 +441,10 @@ class TestWindow(Gtk.Window):
self.editor = TextEditor()
self.editor.show()
windowbox.pack_end(self.editor, True, True, 0)
self.set_size_request(200,200)
self.set_size_request(200, 200)
self.show()
self.maximize()
self.connect("destroy", Gtk.main_quit)
self.editor.text = "this is some inserted text"
self.editor.append("\nLine 3")
@ -461,32 +453,31 @@ class TestWindow(Gtk.Window):
self.editor.cursor_to_start()
self.editor.undo_max = 100
cut_button = Gtk.Button("Cut")
cut_button.connect("clicked",self.editor.cut)
cut_button.connect("clicked", self.editor.cut)
cut_button.show()
windowbox.pack_start(cut_button, False, False, 0)
copy_button = Gtk.Button("Copy")
copy_button.connect("clicked",self.editor.copy)
copy_button.connect("clicked", self.editor.copy)
copy_button.show()
windowbox.pack_start(copy_button, False, False, 0)
paste_button = Gtk.Button("Paste")
paste_button.connect("clicked",self.editor.paste)
paste_button.connect("clicked", self.editor.paste)
paste_button.show()
windowbox.pack_start(paste_button, False, False, 0)
undo_button = Gtk.Button("Undo")
undo_button.connect("clicked",self.editor.undo)
undo_button.connect("clicked", self.editor.undo)
undo_button.show()
windowbox.pack_start(undo_button, False, False, 0)
redo_button = Gtk.Button("Redo")
redo_button.connect("clicked",self.editor.redo)
redo_button.connect("clicked", self.editor.redo)
redo_button.show()
windowbox.pack_start(redo_button, False, False, 0)
if __name__== "__main__":
test = TestWindow()
if __name__ == "__main__":
TEST = TestWindow()
Gtk.main()

View File

@ -286,7 +286,7 @@ class Application(Gtk.Application):
action.set_state(value)
self.settings.set_value("dark-mode",
GLib.Variant("b", value))
self.window.dark_mode_toggled(value)
self.window.toggle_dark_mode(value)
#this changes the headerbar theme accordingly
self.dark_setting = Gtk.Settings.get_default()