diff options
| -rw-r--r-- | UpdateManager/ReleaseNotesViewer.py | 117 | ||||
| -rw-r--r-- | UpdateManager/UpdateManager.py | 5 | ||||
| -rw-r--r-- | data/UpdateManager.glade | 24 |
3 files changed, 125 insertions, 21 deletions
diff --git a/UpdateManager/ReleaseNotesViewer.py b/UpdateManager/ReleaseNotesViewer.py new file mode 100644 index 00000000..9cecc895 --- /dev/null +++ b/UpdateManager/ReleaseNotesViewer.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python + +import pygtk +import gtk +import pango +import subprocess +import os + +class ReleaseNotesViewer(gtk.TextView): + def __init__(self, notes): + gtk.TextView.__init__(self) + self.hovering = False + self.buffer = gtk.TextBuffer() + self.set_buffer(self.buffer) + self.buffer.set_text(notes) + self.connect("event-after", self.event_after) + self.connect("motion-notify-event", self.motion_notify_event) + self.connect("visibility-notify-event", self.visibility_notify_event) + self.search_links() + self.set_property("editable", False) + self.set_cursor_visible(False) + + def tag_link(self, start, end, url): + tag = self.buffer.create_tag(None, foreground="blue", + underline=pango.UNDERLINE_SINGLE) + tag.set_data("url", url) + self.buffer.apply_tag(tag , start, end) + + def search_links(self): + iter = self.buffer.get_iter_at_offset(0) + while 1: + ret = iter.forward_search("http://", gtk.TEXT_SEARCH_VISIBLE_ONLY, + None) + if not ret: + break + (match_start, match_end) = ret + match_tmp = match_end.copy() + while 1: + if match_tmp.forward_char(): + text = match_end.get_text(match_tmp) + if text in (" ", ")", "]", "\n", "\t"): + break + else: + break + match_end = match_tmp.copy() + url = match_start.get_text(match_end) + self.tag_link(match_start, match_end, url) + iter = match_end + + def event_after(self, text_view, event): + if event.type != gtk.gdk.BUTTON_RELEASE: + return False + if event.button != 1: + return False + + try: + (start, end) = self.buffer.get_selection_bounds() + except ValueError: + pass + else: + if start.get_offset() != end.get_offset(): + return False + + (x, y) = self.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET, + int(event.x), int(event.y)) + iter = self.get_iter_at_location(x, y) + + tags = iter.get_tags() + for tag in tags: + url = tag.get_data("url") + if url != "": + self.open_url(url) + break + + def open_url(self, url): + if os.path.exists('usr/bin/gnome-open'): + command = ['gnome-open', url] + else: + command = ['x-www-browser', url] + + if os.getuid() == 0 and os.environ.has_key('SUDO_USER'): + command = ['sudo', '-u', os.environ['SUDO_USER']] + command + + subprocess.Popen(command) + + def motion_notify_event(self, text_view, event): + x, y = text_view.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET, + int(event.x), int(event.y)) + self.check_hovering(x, y) + self.window.get_pointer() + return False + + def visibility_notify_event(self, text_view, event): + (wx, wy, mod) = text_view.window.get_pointer() + (bx, by) = text_view.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET, wx, + wy) + self.check_hovering(bx, by) + return False + + def check_hovering(self, x, y): + _hovering = False + iter = self.get_iter_at_location(x, y) + + tags = iter.get_tags() + for tag in tags: + url = tag.get_data("url") + if url != "": + _hovering = True + break + + if _hovering != self.hovering: + self.hovering = _hovering + + if self.hovering: + self.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2)) + else: + self.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(gtk.gdk.Cursor(gtk.gdk.XTERM)) diff --git a/UpdateManager/UpdateManager.py b/UpdateManager/UpdateManager.py index 6f9e117f..f73f790a 100644 --- a/UpdateManager/UpdateManager.py +++ b/UpdateManager/UpdateManager.py @@ -55,6 +55,7 @@ from gettext import gettext as _ from Common.utils import * from Common.SimpleGladeApp import SimpleGladeApp +from ReleaseNotesViewer import ReleaseNotesViewer import GtkProgress from MetaRelease import Dist, MetaRelease @@ -644,7 +645,9 @@ class UpdateManager(SimpleGladeApp): try: release_notes = urllib2.urlopen(uri) notes = release_notes.read() - self.textview_release_notes.get_buffer().set_text(notes) + textview_release_notes = ReleaseNotesViewer(notes) + textview_release_notes.show() + self.scrolled_notes.add(textview_release_notes) self.dialog_release_notes.set_transient_for(self.window_main) res = self.dialog_release_notes.run() self.dialog_release_notes.hide() diff --git a/data/UpdateManager.glade b/data/UpdateManager.glade index e9f2b32d..400a4f75 100644 --- a/data/UpdateManager.glade +++ b/data/UpdateManager.glade @@ -981,8 +981,8 @@ Need to get the changes from the central server</property> <property name="visible">True</property> <property name="can_default">True</property> <property name="can_focus">True</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> + <property name="label">_Upgrade</property> + <property name="use_underline">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> <property name="focus_on_click">True</property> <property name="response_id">-5</property> @@ -998,7 +998,7 @@ Need to get the changes from the central server</property> </child> <child> - <widget class="GtkScrolledWindow" id="scrolledwindow5"> + <widget class="GtkScrolledWindow" id="scrolled_notes"> <property name="border_width">6</property> <property name="visible">True</property> <property name="can_focus">True</property> @@ -1008,23 +1008,7 @@ Need to get the changes from the central server</property> <property name="window_placement">GTK_CORNER_TOP_LEFT</property> <child> - <widget class="GtkTextView" id="textview_release_notes"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">False</property> - <property name="overwrite">False</property> - <property name="accepts_tab">True</property> - <property name="justification">GTK_JUSTIFY_LEFT</property> - <property name="wrap_mode">GTK_WRAP_NONE</property> - <property name="cursor_visible">False</property> - <property name="pixels_above_lines">6</property> - <property name="pixels_below_lines">0</property> - <property name="pixels_inside_wrap">0</property> - <property name="left_margin">6</property> - <property name="right_margin">6</property> - <property name="indent">0</property> - <property name="text" translatable="yes"></property> - </widget> + <placeholder/> </child> </widget> <packing> |
