summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--UpdateManager/ReleaseNotesViewer.py117
-rw-r--r--UpdateManager/UpdateManager.py5
-rw-r--r--data/UpdateManager.glade24
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>