From eed1c95a264c979ed76f51d49142f31062c01a7c Mon Sep 17 00:00:00 2001 From: Wolf Vollprecht Date: Mon, 1 Sep 2014 23:07:18 +0200 Subject: [PATCH] several improvements, also introducing several new bugs --- data/media/style.css | 66 +++++++--- data/ui/UberwriterWindow.ui | 2 +- uberwriter/UberwriterInlinePreview.py | 177 +++++++++++++++++++++++++- uberwriter/UberwriterWindow.py | 143 +++++++++++++-------- 4 files changed, 310 insertions(+), 78 deletions(-) diff --git a/data/media/style.css b/data/media/style.css index f3d6c44..a2fcd25 100644 --- a/data/media/style.css +++ b/data/media/style.css @@ -4,6 +4,8 @@ inclusion in templates */ +@define-color dark_bg #333; + @binding-set window-bindings { bind "n" { "new-file" () }; bind "o" { "open-file" () }; @@ -12,6 +14,9 @@ bind "d" { "toggle-focusmode" () }; bind "p" { "toggle-preview" () }; bind "w" { "close-window" () }; + bind "f" { "toggle-search" () }; + bind "r" { "toggle-search-replace" () }; + bind "f" { "toggle-search-replace" () }; bind "F11" { "toggle-fullscreen" () }; } @@ -24,11 +29,6 @@ bind "z" { "undo" () }; bind "y" { "redo" () }; bind "z" { "redo" () }; - - -} - -GtkRevealer { } #UberwriterWindow { @@ -37,16 +37,33 @@ GtkRevealer { border-radius: 7px 7px 5px 5px; } -.scrollbars-junction, -.scrollbar.trough { - background-image: none; - background-color: transparent; - border-width: 0; - border-radius: 0; - border-image: none; +#UberwriterWindow.small #UberwriterEditor { + font: Inconsolata 12; } -#UberwriterWindow GtkTextView { +#UberwriterWindow.medium #UberwriterEditor { + font: Inconsolata 15; +} + +#UberwriterWindow.large #UberwriterEditor { + font: Inconsolata 17; +} + +#UberwriterWindow.dark_mode { + background: #333; +} + +#UberwriterWindow.dark_mode #UberwriterEditor { + color: #CCC; + -GtkWidget-cursor-color: shade(#4D9FCE, 0.9); +} + +.scrollbars-junction, +.scrollbar.trough { + background-color: transparent; +} + +#UberwriterEditor { border: none; color: #222; -GtkWidget-cursor-color: shade(#4D9FCE, 0.9); @@ -54,7 +71,12 @@ GtkRevealer { gtk-key-bindings: editor-bindings; } -#UberwriterWindow GtkTextView GtkButton { +#UberwriterEditor:selected { + background-color: #4D9FCE; + color: #FFF; +} + +#UberwriterEditor GtkButton { margin: 0; padding: 0; /*background: #CCC;*/ @@ -66,10 +88,6 @@ GtkRevealer { padding: 0; } -#UberwriterWindow GtkTextView:selected { - background-color: #4D9FCE; - color: #FFF; -} #status_bar_box GtkLabel { color: #666; @@ -107,6 +125,7 @@ GtkRevealer { transition: 500ms ease-in; } + #status_bar_box GtkButton:hover, #status_bar_box GtkButton:active:hover { transition: 0s ease-in; @@ -121,6 +140,13 @@ GtkRevealer { background-image: none; box-shadow: 0 0 2px rgba(0,0,0,0.4) } +.dark_mode #status_bar_box GtkButton { + background: #F00; +} +.dark_mode #status_bar_box GtkButton:hover, +.dark_mode #status_bar_box GtkButton:active { + background-color: shade(@dark_bg, 0.8); +} #status_bar_box GtkSeparator { border-color: #999; @@ -138,4 +164,8 @@ GtkRevealer { #UberwriterWindow GtkTreeView { color: #333; font-size: 10px; +} + +#LexikonBubble { + font: Inconsolata 10; } \ No newline at end of file diff --git a/data/ui/UberwriterWindow.ui b/data/ui/UberwriterWindow.ui index 14009ec..044c9ec 100644 --- a/data/ui/UberwriterWindow.ui +++ b/data/ui/UberwriterWindow.ui @@ -414,7 +414,7 @@ - + True True diff --git a/uberwriter/UberwriterInlinePreview.py b/uberwriter/UberwriterInlinePreview.py index 8db8ca1..332729e 100644 --- a/uberwriter/UberwriterInlinePreview.py +++ b/uberwriter/UberwriterInlinePreview.py @@ -46,6 +46,115 @@ GObject.threads_init() # Still needed? # A jumping URL from that (for preview) # Also, after going to preview, set cursor back to where it was +import telnetlib + +class DictAccessor(object): + def __init__( self, host='localhost', port=2628, timeout=60 ): + self.tn = telnetlib.Telnet( host, port ) + self.timeout = timeout + self.login_response = self.tn.expect( [ self.reEndResponse ], self.timeout )[ 2 ] + bytes + def runCommand( self, cmd ): + self.tn.write( cmd.encode('utf-8') + b'\r\n' ) + return self.tn.expect( [ self.reEndResponse ], self.timeout )[ 2 ] + + def getMatches( self, database, strategy, word ): + if database in [ '', 'all' ]: + d = '*' + else: + d = database + if strategy in [ '', 'default' ]: + s = '.' + else: + s = strategy + w = word.replace( '"', r'\"' ) + tsplit = self.runCommand( 'MATCH %s %s "%s"' % ( d, s, w ) ).splitlines( ) + mlist = list( ) + if tsplit[ -1 ].startswith( b'250 ok' ) and tsplit[ 0 ].startswith( b'1' ): + mlines = tsplit[ 1:-2 ] + for line in mlines: + lsplit = line.strip( ).split( ) + db = lsplit[ 0 ] + word = unquote( ' '.join( lsplit[ 1: ] ) ) + mlist.append( ( db, word ) ) + return mlist + + reEndResponse = re.compile( b'^[2-5][0-58][0-9] .*\r\n$', re.DOTALL + re.MULTILINE ) + reDefinition = re.compile( b'^151(.*?)^\.', re.DOTALL + re.MULTILINE ) + + def getDefinition( self, database, word ): + if database in [ '', 'all' ]: + d = '*' + else: + d = database + w = word.replace( '"', r'\"' ) + dsplit = self.runCommand( 'DEFINE %s "%s"' % ( d, w ) ).splitlines( True ) + dlist = list( ) + if dsplit[ -1 ].startswith( b'250 ok' ) and dsplit[ 0 ].startswith( b'1' ): + dlines = dsplit[ 1:-1 ] + dtext = b''.join( dlines ) + dlist = self.reDefinition.findall( dtext ) + #dlist = [ dtext ] + return dlist + + def close( self ): + t = self.runCommand( 'QUIT' ) + self.tn.close( ) + return t + + def parse_wordnet(self, response): + # consisting of group (n,v,adj,adv) + # number, description, examples, synonyms, antonyms + capture = {} + lines = response.splitlines() + lines = lines[2:] + lines = ' '.join(lines) + lines = re.sub('\s+', ' ', lines).strip() + lines = re.split(r'( adv | adj | n | v |^adv |^adj |^n |^v )', lines) + res = {} + for l in lines: + l = l.strip() + act_res = {} + act_res['defs'] = [] + if len(l) == 0: + continue + if l in ['adv', 'adj','n','v']: + act_res['class'] = l + else: + ll = re.split('(?: |^)(\d): ', l) + # print(ll) + act_def = {} + for lll in ll: + # print (lll) + if lll.strip().isdigit() or not lll.strip(): + if 'description' in act_def and act_def['description']: + act_res['defs'].append(act_def.copy()) + act_def = {'num': lll} + continue + a = re.findall(r'(\[(syn|ant): (.+?)\] ??)+', lll) + for n in a: + if n[1] == 'syn': + act_def['syn'] = re.findall(r'\{(.*?)\}.*?', n[2]) + else: + act_def['ant'] = re.findall(r'\{(.*?)\}.*?', n[2]) + tbr = re.search(r'\[.+\]', lll) + if tbr: + lll = lll[:tbr.start()] + lll = lll.split(';') + act_def['examples'] = [] + act_def['description'] = [] + for llll in lll: + llll = llll.strip() + if(llll.strip().startswith('"')): + act_def['examples'].append(llll) + else: + act_def['description'].append(llll) + + if act_def and 'description' in act_def: + act_res['defs'].append(act_def.copy()) + + print(act_res) + return act_res def check_url(url, item, spinner): logger.debug("thread started, checking url") error = False @@ -65,6 +174,22 @@ def check_url(url, item, spinner): spinner.destroy() item.set_label(text) +def get_dictionary(term): + def parse_response(response): + # consisting of group (n,v,adj,adv) + # number, description, examples, synonyms, antonyms + lines = response.split('\n') + lines = lines[2:] + for l in lines: + l = l.lstrip() + print(l) + + da = DictAccessor() + output = da.getDefinition('wn', term) + print (output) + + output = output[0] + return da.parse_wordnet(output.decode(encoding='UTF-8')) def get_web_thumbnail(url, item, spinner): logger.debug("thread started, generating thumb") @@ -91,6 +216,15 @@ def get_web_thumbnail(url, item, spinner): item.add(image) item.show() +def fill_lexikon_bubble(vocab, lexikon_dict): + grid = Gtk.Grid.new() + i = 0 + for entry in lexikon_dict: + grid.attach(Gtk.Label.new(vocab + ' ~ ' + entry['class']), i, i, 3, 1) + grid.show_all() + return grid + + class UberwriterInlinePreview(): @@ -106,6 +240,19 @@ class UberwriterInlinePreview(): self.TextView.connect_after('popup-menu', self.move_popup) self.TextView.connect('button-press-event', self.click_move_button) + def open_popover_with_widget(self, widget): + a = self.TextBuffer.create_child_anchor(self.TextBuffer.get_iter_at_mark(self.ClickMark)) + b = Gtk.Grid.new() + self.TextView.add_child_at_anchor(b, a) + b.show() + popover = Gtk.Popover.new(b) + dismiss, rect = popover.get_pointing_to() + rect.y = rect.y - 20 + popover.set_pointing_to(rect) + popover.add(widget) + popover.show_all() + popover.set_property('width-request', 50) + def click_move_button(self, widget, event): if event.button == 3: x, y = self.TextView.window_to_buffer_coords(2, @@ -120,10 +267,10 @@ class UberwriterInlinePreview(): f.fix_table() def populate_popup(self, editor, menu, data=None): - popover = Gtk.Popover.new(editor) + # popover = Gtk.Popover.new(editor) # pop_cont = Gtk.Container.new() # popover.add(pop_cont) - popover.show_all() + # popover.show_all() item = Gtk.MenuItem.new() item.set_name("PreviewMenuItem") @@ -169,10 +316,7 @@ class UberwriterInlinePreview(): image.show() logger.debug("logging image") # item.add(image) - popover.add(image) - popover.show_all() - item.set_property('width-request', 50) - popover.set_property('width-request', 50) + self.open_popover_with_widget(image) else: label = Gtk.Label() msg = 'Formula looks incorrect:\n' + result @@ -295,6 +439,27 @@ class UberwriterInlinePreview(): menu.show() found_match = True break + + if not found_match: + start_iter = self.TextBuffer.get_iter_at_mark(self.ClickMark) + start_iter.backward_word_start() + end_iter = start_iter.copy() + end_iter.forward_word_end() + word = self.TextBuffer.get_text(start_iter, end_iter, False) + print(word) + terms = get_dictionary(word) + sc = Gtk.ScrolledWindow.new() + # tv = Gtk.TextView.new() + # tv.set_editable(False) + # tv.set_name('LexikonBubble') + + sc.add(fill_lexikon_bubble(word, get_dictionary(word))) + sc.props.width_request = 500 + sc.props.height_request = 400 + tv.get_buffer().set_text(terms) + sc.show_all() + self.open_popover_with_widget(sc) + return def move_popup(self): diff --git a/uberwriter/UberwriterWindow.py b/uberwriter/UberwriterWindow.py index abdc767..d04fb91 100644 --- a/uberwriter/UberwriterWindow.py +++ b/uberwriter/UberwriterWindow.py @@ -84,6 +84,8 @@ class UberwriterWindow(Window): 'toggle-fullscreen': (GObject.SIGNAL_ACTION, None, ()), 'toggle-spellcheck': (GObject.SIGNAL_ACTION, None, ()), 'toggle-preview': (GObject.SIGNAL_ACTION, None, ()), + 'toggle-search': (GObject.SIGNAL_ACTION, None, ()), + 'toggle-search-replace': (GObject.SIGNAL_ACTION, None, ()), 'close-window': (GObject.SIGNAL_ACTION, None, ()) } @@ -138,10 +140,10 @@ class UberwriterWindow(Window): length = 0 self.word_count.set_text(str(length)) - def mark_set(self, buffer, location, mark, data=None): - if mark.get_name() == 'insert': - self.check_scroll() + if mark.get_name() in ['insert', 'gtk_drag_target']: + self.check_scroll(mark) + return True def text_changed(self, widget, data=None): if self.did_change == False: @@ -154,7 +156,7 @@ class UberwriterWindow(Window): self.buffer_modified_for_status_bar = True self.update_line_and_char_count() - self.check_scroll() + self.check_scroll(self.TextBuffer.get_insert()) def toggle_fullscreen(self, widget, data=None): if widget.get_active(): @@ -179,10 +181,9 @@ class UberwriterWindow(Window): self.MarkupBuffer.focusmode_highlight() self.focusmode = True self.TextEditor.grab_focus() - self.check_scroll() + self.check_scroll(self.TextBuffer.get_insert()) if self.spellcheck != False: self.SpellChecker._misspelled.set_property('underline', 0) - else: self.remove_typewriter() self.focusmode = False @@ -222,11 +223,10 @@ class UberwriterWindow(Window): widget.get_vadjustment().props.value = pos return True # continue ticking - def check_scroll(self): + def check_scroll(self, mark): gradient_offset = 80 buf = self.TextEditor.get_buffer() - ins = buf.get_insert() - ins_it = buf.get_iter_at_mark(ins) + ins_it = buf.get_iter_at_mark(mark) loc_rect = self.TextEditor.get_iter_location(ins_it) # alignment offset added from top @@ -264,29 +264,34 @@ class UberwriterWindow(Window): width_request = 600 if(w_width < 900): self.MarkupBuffer.set_multiplier(8) - pango_font = Pango.FontDescription("Inconsolata 12px") - self.TextEditor.modify_font(pango_font) self.current_font_size = 12 self.alignment_padding = 30 lm = 7 * 8 + self.get_style_context().remove_class("medium") + self.get_style_context().remove_class("large") + self.get_style_context().add_class("small") elif(w_width < 1400): self.MarkupBuffer.set_multiplier(10) - pango_font = Pango.FontDescription("Inconsolata 15px") - self.TextEditor.modify_font(pango_font) width_request = 800 self.current_font_size = 15 self.alignment_padding = 40 lm = 7 * 10 + self.get_style_context().remove_class("small") + self.get_style_context().remove_class("large") + self.get_style_context().add_class("medium") + else: self.MarkupBuffer.set_multiplier(13) - pango_font = Pango.FontDescription("Inconsolata 17px") - self.TextEditor.modify_font(pango_font) self.current_font_size = 17 width_request = 1000 self.alignment_padding = 60 lm = 7 * 13 + self.get_style_context().remove_class("medium") + self.get_style_context().remove_class("small") + self.get_style_context().add_class("large") + self.EditorAlignment.props.top_padding = self.alignment_padding self.EditorAlignment.props.bottom_padding = self.alignment_padding self.TextEditor.set_left_margin(lm) @@ -356,9 +361,9 @@ class UberwriterWindow(Window): filechooser.destroy() return response - elif response == Gtk.ResponseType.CANCEL: + else: filechooser.destroy() - return response + return Gtk.ResponseType.CANCEL def save_document_as(self, widget, data=None): filechooser = Gtk.FileChooserDialog( @@ -398,8 +403,9 @@ class UberwriterWindow(Window): filechooser.destroy() self.did_change = False - elif response == Gtk.ResponseType.CANCEL: + else: filechooser.destroy() + return Gtk.ResponseType.CANCEL def export(self, export_type="html"): filechooser = Gtk.FileChooserDialog( @@ -530,10 +536,12 @@ class UberwriterWindow(Window): ) dialog.add_button(_("Close without Saving"), Gtk.ResponseType.NO) dialog.add_button(_("Cancel"), Gtk.ResponseType.CANCEL) - dialog.add_button(_("Save now"), Gtk.ResponseType.YES).grab_focus() + dialog.add_button(_("Save now"), Gtk.ResponseType.YES) dialog.set_title(_('Unsaved changes')) dialog.set_default_size(200, 150) + dialog.set_default_response(Gtk.ResponseType.YES) response = dialog.run() + if response == Gtk.ResponseType.YES: title = self.get_title() if self.save_document(widget = None) == Gtk.ResponseType.CANCEL: @@ -542,12 +550,12 @@ class UberwriterWindow(Window): else: dialog.destroy() return response - elif response == Gtk.ResponseType.CANCEL: - dialog.destroy() - return response elif response == Gtk.ResponseType.NO: dialog.destroy() return response + else: + dialog.destroy() + return Gtk.ResponseType.CANCEL def new_document(self, widget): if self.check_change() == Gtk.ResponseType.CANCEL: @@ -604,10 +612,10 @@ class UberwriterWindow(Window): def on_drag_data_received(self, widget, drag_context, x, y, data, info, time): """Handle drag and drop events""" - if info == 1: # uri target uris = data.get_uris() + print(uris) for uri in uris: uri = urllib.parse.unquote_plus(uri) mime = mimetypes.guess_type(uri) @@ -622,21 +630,28 @@ class UberwriterWindow(Window): text = "[Insert link title here](%s)" % uri ll = 1 lr = 22 - + self.TextBuffer.place_cursor(self.TextBuffer.get_iter_at_mark( + self.TextBuffer.get_mark('gtk_drag_target'))) self.TextBuffer.insert_at_cursor(text) insert_mark = self.TextBuffer.get_insert() selection_bound = self.TextBuffer.get_selection_bound() cursor_iter = self.TextBuffer.get_iter_at_mark(insert_mark) cursor_iter.backward_chars(len(text) - ll) + print('move_cursor') self.TextBuffer.move_mark(insert_mark, cursor_iter) cursor_iter.forward_chars(lr) self.TextBuffer.move_mark(selection_bound, cursor_iter) + print('move selection') elif info == 2: # Text target + self.TextBuffer.place_cursor(self.TextBuffer.get_iter_at_mark( + self.TextBuffer.get_mark('gtk_drag_target'))) self.TextBuffer.insert_at_cursor(data.get_text()) - + Gtk.drag_finish(drag_context, True, True, time) self.present() + print("returning true") + return False def toggle_preview(self, widget, data=None): if widget.get_active(): @@ -680,6 +695,7 @@ class UberwriterWindow(Window): self.TextEditor.show() self.queue_draw() + return True def on_click_link(self, view, frame, req, data=None): # This provide ability for self.webview to open links in default browser @@ -692,30 +708,25 @@ class UberwriterWindow(Window): self.dark_mode = widget.get_active() if self.dark_mode: # Dark Mode is on - css = open(helpers.get_media_path('style_dark.css'), 'rb') - css_data = css.read() - css.close() - self.style_provider.load_from_data(css_data) - # self.background_image = helpers.get_media_path('bg_dark.png') + self.gtk_settings.set_property('gtk-application-prefer-dark-theme', True) + self.get_style_context().add_class("dark_mode") self.MarkupBuffer.dark_mode(True) - + # self.background_image = helpers.get_media_path('bg_dark.png') else: # Dark mode off - css = open(helpers.get_media_path('style.css'), 'rb') - css_data = css.read() - css.close() - self.style_provider.load_from_data(css_data) - # self.background_image = helpers.get_media_path('bg_light.png') + self.gtk_settings.set_property('gtk-application-prefer-dark-theme', False) + self.get_style_context().remove_class("dark_mode") self.MarkupBuffer.dark_mode(False) + # self.background_image = helpers.get_media_path('bg_light.png') # surface = cairo.ImageSurface.create_from_png(self.background_image) # self.background_pattern = cairo.SurfacePattern(surface) # self.background_pattern.set_extend(cairo.EXTEND_REPEAT) - Gtk.StyleContext.add_provider_for_screen( - Gdk.Screen.get_default(), self.style_provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION - ) + # Gtk.StyleContext.add_provider_for_screen( + # Gdk.Screen.get_default(), self.style_provider, + # Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION + # ) # Redraw contents of window (self) self.queue_draw() @@ -807,7 +818,8 @@ class UberwriterWindow(Window): def poll_for_motion(self): if (self.was_motion == False and self.status_bar_visible - and self.buffer_modified_for_status_bar): + and self.buffer_modified_for_status_bar + and self.TextEditor.props.has_focus): # self.status_bar.set_state_flags(Gtk.StateFlags.INSENSITIVE, True) self.statusbar_revealer.set_reveal_child(False) self.hb_revealer.set_reveal_child(False) @@ -838,20 +850,33 @@ class UberwriterWindow(Window): GObject.timeout_add(3000, self.poll_for_motion) self.was_motion = True + def focus_out(self, widget, data=None): + if self.status_bar_visible == False: + self.statusbar_revealer.set_reveal_child(True) + self.hb_revealer.set_reveal_child(True) + self.hb.props.opacity = 1 + self.status_bar_visible = True + self.buffer_modified_for_status_bar = False + self.update_line_and_char_count() + def draw_gradient(self, widget, cr): + bg_color = self.get_style_context().get_background_color(Gtk.StateFlags.ACTIVE) + lg_top = cairo.LinearGradient(0, 0, 0, 80) - lg_top.add_color_stop_rgba(0, 1, 1, 1, 1) - lg_top.add_color_stop_rgba(1, 1, 1, 1, 0) + lg_top.add_color_stop_rgba(0, bg_color.red, bg_color.green, bg_color.blue, 1) + lg_top.add_color_stop_rgba(1, bg_color.red, bg_color.green, bg_color.blue, 0) + width = widget.get_allocation().width height = widget.get_allocation().height + cr.rectangle(0, 0, width, 80) cr.set_source(lg_top) cr.fill() cr.rectangle(0, height - 80, width, height) lg_btm = cairo.LinearGradient(0, height - 80, 0, height) - lg_btm.add_color_stop_rgba(1, 1, 1, 1, 1) - lg_btm.add_color_stop_rgba(0, 1, 1, 1, 0) + lg_btm.add_color_stop_rgba(1, bg_color.red, bg_color.green, bg_color.blue, 1) + lg_btm.add_color_stop_rgba(0, bg_color.red, bg_color.green, bg_color.blue, 0) cr.set_source(lg_btm) cr.fill() @@ -873,6 +898,7 @@ class UberwriterWindow(Window): self.connect('toggle-preview', self.menu_activate_preview) self.connect('toggle-spellcheck', self.toggle_spellcheck) self.connect('close-window', self.on_mnu_close_activate) + self.connect('toggle-search', self.open_search_and_replace) self.scroll_adjusted = False # Code for other initialization actions should be added here. @@ -887,6 +913,7 @@ class UberwriterWindow(Window): self.hb = Gtk.HeaderBar() self.hb_revealer.add(self.hb) self.hb_revealer.props.transition_duration = 1000 + self.hb_revealer.props.transition_type = Gtk.RevealerTransitionType.CROSSFADE self.hb.props.show_close_button = True self.hb.get_style_context().add_class("titlebar") self.set_titlebar(self.hb_revealer) @@ -906,6 +933,7 @@ class UberwriterWindow(Window): self.hb.pack_end(btn_settings) self.hb.show_all() + self.title_end = " – UberWriter" self.set_headerbar_title("New File" + self.title_end) @@ -941,6 +969,7 @@ class UberwriterWindow(Window): # Setup light background self.TextEditor = TextEditor() + self.TextEditor.set_name('UberwriterEditor') base_leftmargin = 40 # self.TextEditor.set_left_margin(base_leftmargin) @@ -949,6 +978,7 @@ class UberwriterWindow(Window): self.TextEditor.props.halign = Gtk.Align.CENTER self.TextEditor.set_vadjustment(builder.get_object('vadjustment1')) self.TextEditor.set_wrap_mode(Gtk.WrapMode.WORD) + self.TextEditor.connect('focus-out-event', self.focus_out) self.TextEditor.show() self.TextEditor.grab_focus() @@ -972,9 +1002,6 @@ class UberwriterWindow(Window): self.PreviewPane = builder.get_object('preview_scrolledwindow') - pangoFont = Pango.FontDescription("Inconsolata 12px") - self.TextEditor.modify_font(pangoFont) - self.TextEditor.set_margin_top(38) self.TextEditor.set_margin_bottom(16) @@ -1015,18 +1042,21 @@ class UberwriterWindow(Window): self.textchange = False self.scroll_count = 0 self.timestamp_last_mouse_motion = 0 - self.TextBuffer.connect('mark-set', self.mark_set) + self.TextBuffer.connect_after('mark-set', self.mark_set) + + # Drag and drop # self.TextEditor.drag_dest_unset() - # Drag and drop - self.TextEditor.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.COPY) - + # self.TextEditor.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.COPY) self.target_list = Gtk.TargetList.new([]) self.target_list.add_uri_targets(1) self.target_list.add_text_targets(2) self.TextEditor.drag_dest_set_target_list(self.target_list) - self.TextEditor.connect('drag-data-received', self.on_drag_data_received) + self.TextEditor.connect_after('drag-data-received', self.on_drag_data_received) + def on_drop(widget, *args): + print("drop") + self.TextEditor.connect('drag-drop', on_drop) self.TextBuffer.connect('paste-done', self.paste_done) @@ -1075,8 +1105,15 @@ class UberwriterWindow(Window): self.connect("configure-event", self.window_resize) self.connect("delete-event", self.on_delete_called) + self.gtk_settings = Gtk.Settings.get_default() self.load_settings(builder) + self.connect_after('realize', self.color_window) + + def color_window(self, widget, data=None): + window_gdk = self.get_window() + window_gdk.set_background(Gdk.Color(0, 1, 0)) + def alt_mod(self, widget, event, data=None): # TODO: Click and open when alt is pressed if event.state & Gdk.ModifierType.MOD2_MASK: