Squashed 'yocto-poky/' content from commit ea562de

git-subtree-dir: yocto-poky
git-subtree-split: ea562de57590c966cd5a75fda8defecd397e6436
diff --git a/bitbake/lib/bb/ui/crumbs/persistenttooltip.py b/bitbake/lib/bb/ui/crumbs/persistenttooltip.py
new file mode 100644
index 0000000..927c194
--- /dev/null
+++ b/bitbake/lib/bb/ui/crumbs/persistenttooltip.py
@@ -0,0 +1,186 @@
+#
+# BitBake Graphical GTK User Interface
+#
+# Copyright (C) 2012   Intel Corporation
+#
+# Authored by Joshua Lock <josh@linux.intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 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 warranty of
+# MERCHANTABILITY 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
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import gobject
+import gtk
+try:
+    import gconf
+except:
+    pass
+
+class PersistentTooltip(gtk.Window):
+    """
+    A tooltip which persists once shown until the user dismisses it with the Esc
+    key or by clicking the close button.
+
+    # FIXME: the PersistentTooltip should be disabled when the user clicks anywhere off
+    # it. We can't do this with focus-out-event becuase modal ensures we have focus?
+
+    markup: some Pango text markup to display in the tooltip
+    """
+    def __init__(self, markup, parent_win=None):
+        gtk.Window.__init__(self, gtk.WINDOW_POPUP)
+
+        # Inherit the system theme for a tooltip
+        style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
+                        'gtk-tooltip', 'gtk-tooltip', gobject.TYPE_NONE)
+        self.set_style(style)
+
+        # The placement of the close button on the tip should reflect how the
+        # window manager of the users system places close buttons. Try to read
+        # the metacity gconf key to determine whether the close button is on the
+        # left or the right.
+        # In the case that we can't determine the users configuration we default
+        # to close buttons being on the right.
+        __button_right = True
+        try:
+            client = gconf.client_get_default()
+            order = client.get_string("/apps/metacity/general/button_layout")
+            if order and order.endswith(":"):
+                __button_right = False
+        except NameError:
+            pass
+
+        # We need to ensure we're only shown once
+        self.shown = False
+
+        # We don't want any WM decorations
+        self.set_decorated(False)
+        # We don't want to show in the taskbar or window switcher
+        self.set_skip_pager_hint(True)
+        self.set_skip_taskbar_hint(True)
+        # We must be modal to ensure we grab focus when presented from a gtk.Dialog
+        self.set_modal(True)
+
+        self.set_border_width(0)
+        self.set_position(gtk.WIN_POS_MOUSE)
+        self.set_opacity(0.95)
+
+        # Ensure a reasonable minimum size
+        self.set_geometry_hints(self, 100, 50)
+
+        # Set this window as a transient window for parent(main window)
+        if parent_win:
+            self.set_transient_for(parent_win)
+            self.set_destroy_with_parent(True)
+        # Draw our label and close buttons
+        hbox = gtk.HBox(False, 0)
+        hbox.show()
+        self.add(hbox)
+
+        img = gtk.Image()
+        img.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_BUTTON)
+
+        self.button = gtk.Button()
+        self.button.set_image(img)
+        self.button.connect("clicked", self._dismiss_cb)
+        self.button.set_flags(gtk.CAN_DEFAULT)
+        self.button.grab_focus()
+        self.button.show()
+        vbox = gtk.VBox(False, 0)
+        vbox.show()
+        vbox.pack_start(self.button, False, False, 0)
+        if __button_right:
+            hbox.pack_end(vbox, True, True, 0)
+        else:
+            hbox.pack_start(vbox, True, True, 0)
+
+        self.set_default(self.button)
+
+        bin = gtk.HBox(True, 6)
+        bin.set_border_width(6)
+        bin.show()
+        self.label = gtk.Label()
+        self.label.set_line_wrap(True)
+        # We want to match the colours of the normal tooltips, as dictated by
+        # the users gtk+-2.0 theme, wherever possible - on some systems this
+        # requires explicitly setting a fg_color for the label which matches the
+        # tooltip_fg_color
+        settings = gtk.settings_get_default()
+        colours = settings.get_property('gtk-color-scheme').split('\n')
+        # remove any empty lines, there's likely to be a trailing one after
+        # calling split on a dictionary-like string
+        colours = filter(None, colours)
+        for col in colours:
+            item, val = col.split(': ')
+            if item == 'tooltip_fg_color':
+                style = self.label.get_style()
+                style.fg[gtk.STATE_NORMAL] = gtk.gdk.color_parse(val)
+                self.label.set_style(style)
+                break # we only care for the tooltip_fg_color
+
+        self.label.set_markup(markup)
+        self.label.show()
+        bin.add(self.label)
+        hbox.pack_end(bin, True, True, 6)
+
+        # add the original URL display for user reference
+        if 'a href' in markup:
+            hbox.set_tooltip_text(self.get_markup_url(markup))
+        hbox.show()
+
+        self.connect("key-press-event", self._catch_esc_cb)
+
+    """
+    Callback when the PersistentTooltip's close button is clicked.
+    Hides the PersistentTooltip.
+    """
+    def _dismiss_cb(self, button):
+        self.hide()
+        return True
+
+    """
+    Callback when the Esc key is detected. Hides the PersistentTooltip.
+    """
+    def _catch_esc_cb(self, widget, event):
+        keyname = gtk.gdk.keyval_name(event.keyval)
+        if keyname == "Escape":
+            self.hide()
+        return True
+
+    """
+    Called to present the PersistentTooltip.
+    Overrides the superclasses show() method to include state tracking.
+    """
+    def show(self):
+        if not self.shown:
+            self.shown = True
+            gtk.Window.show(self)
+
+    """
+    Called to hide the PersistentTooltip.
+    Overrides the superclasses hide() method to include state tracking.
+    """
+    def hide(self):
+        self.shown = False
+        gtk.Window.hide(self)
+
+    """
+    Called to get the hyperlink URL from markup text.
+    """
+    def get_markup_url(self, markup):
+        url = "http:"
+        if markup and type(markup) == str:
+            s = markup
+            if 'http:' in s:
+                import re
+                url = re.search('(http:[^,\\ "]+)', s).group(0)
+
+        return url