From 340b2b5612875e6544fd0f6e45e37e7206dd6db2 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Fri, 14 Nov 2008 11:38:10 +0000 Subject: bitbake-dev: Refactor goggle to pull out useful components. Separate the GTK components and abstractions to a separate module where they can be used by other user interfaces. This module includes the model, the view and abstraction that populates the model. --- bitbake-dev/lib/bb/ui/crumbs/__init__.py | 18 +++ bitbake-dev/lib/bb/ui/crumbs/runningbuild.py | 169 +++++++++++++++++++++++++++ bitbake-dev/lib/bb/ui/goggle.py | 146 +---------------------- 3 files changed, 188 insertions(+), 145 deletions(-) create mode 100644 bitbake-dev/lib/bb/ui/crumbs/__init__.py create mode 100644 bitbake-dev/lib/bb/ui/crumbs/runningbuild.py (limited to 'bitbake-dev/lib/bb/ui') diff --git a/bitbake-dev/lib/bb/ui/crumbs/__init__.py b/bitbake-dev/lib/bb/ui/crumbs/__init__.py new file mode 100644 index 000000000..c6a377a8e --- /dev/null +++ b/bitbake-dev/lib/bb/ui/crumbs/__init__.py @@ -0,0 +1,18 @@ +# +# BitBake UI Implementation +# +# Copyright (C) 2006-2007 Richard Purdie +# +# 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. + diff --git a/bitbake-dev/lib/bb/ui/crumbs/runningbuild.py b/bitbake-dev/lib/bb/ui/crumbs/runningbuild.py new file mode 100644 index 000000000..b9aba5b8c --- /dev/null +++ b/bitbake-dev/lib/bb/ui/crumbs/runningbuild.py @@ -0,0 +1,169 @@ +# +# BitBake Graphical GTK User Interface +# +# Copyright (C) 2008 Intel Corporation +# +# Authored by Rob Bradford +# +# 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 + +class RunningBuildModel (gtk.TreeStore): + (COL_TYPE, COL_PACKAGE, COL_TASK, COL_MESSAGE, COL_ICON, COL_ACTIVE) = (0, 1, 2, 3, 4, 5) + def __init__ (self): + gtk.TreeStore.__init__ (self, + gobject.TYPE_STRING, + gobject.TYPE_STRING, + gobject.TYPE_STRING, + gobject.TYPE_STRING, + gobject.TYPE_STRING, + gobject.TYPE_BOOLEAN) + +class RunningBuild (gobject.GObject): + __gsignals__ = { + 'build-finished' : (gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, + ()) + } + pids_to_task = {} + tasks_to_iter = {} + + def __init__ (self): + gobject.GObject.__init__ (self) + self.model = RunningBuildModel() + + def handle_event (self, event): + # Handle an event from the event queue, this may result in updating + # the model and thus the UI. Or it may be to tell us that the build + # has finished successfully (or not, as the case may be.) + + parent = None + pid = 0 + package = None + task = None + + # If we have a pid attached to this message/event try and get the + # (package, task) pair for it. If we get that then get the parent iter + # for the message. + if event[1].has_key ('pid'): + pid = event[1]['pid'] + if self.pids_to_task.has_key(pid): + (package, task) = self.pids_to_task[pid] + parent = self.tasks_to_iter[(package, task)] + + if event[0].startswith('bb.msg.Msg'): + # Set a pretty icon for the message based on it's type. + if (event[0].startswith ('bb.msg.MsgWarn')): + icon = "dialog-warning" + elif (event[0].startswith ('bb.msg.MsgErr')): + icon = "dialog-error" + else: + icon = None + + # Ignore the "Running task i of n .." messages + if (event[1]['_message'].startswith ("Running task")): + return + + # Add the message to the tree either at the top level if parent is + # None otherwise as a descendent of a task. + self.model.append (parent, + (event[0].split()[-1], # e.g. MsgWarn, MsgError + package, + task, + event[1]['_message'], + icon, + False)) + elif event[0].startswith('bb.build.TaskStarted'): + (package, task) = (event[1]['_package'], event[1]['_task']) + + # Save out this PID. + self.pids_to_task[pid] = (package,task) + + # Check if we already have this package in our model. If so then + # that can be the parent for the task. Otherwise we create a new + # top level for the package. + if (self.tasks_to_iter.has_key ((package, None))): + parent = self.tasks_to_iter[(package, None)] + else: + parent = self.model.append (None, (None, + package, + None, + "Package: %s" % (package), + None, + False)) + self.tasks_to_iter[(package, None)] = parent + + # Because this parent package now has an active child mark it as + # such. + self.model.set(parent, self.model.COL_ICON, "gtk-execute") + + # Add an entry in the model for this task + i = self.model.append (parent, (None, + package, + task, + "Task: %s" % (task), + None, + False)) + + # Save out the iter so that we can find it when we have a message + # that we need to attach to a task. + self.tasks_to_iter[(package, task)] = i + + # Mark this task as active. + self.model.set(i, self.model.COL_ICON, "gtk-execute") + + elif event[0].startswith('bb.build.Task'): + + if event[0].startswith('bb.build.TaskFailed'): + # Mark the task as failed + i = self.tasks_to_iter[(package, task)] + self.model.set(i, self.model.COL_ICON, "dialog-error") + + # Mark the parent package as failed + i = self.tasks_to_iter[(package, None)] + self.model.set(i, self.model.COL_ICON, "dialog-error") + else: + # Mark the task as inactive + i = self.tasks_to_iter[(package, task)] + self.model.set(i, self.model.COL_ICON, None) + + # Mark the parent package as inactive + i = self.tasks_to_iter[(package, None)] + self.model.set(i, self.model.COL_ICON, None) + + + # Clear the iters and the pids since when the task goes away the + # pid will no longer be used for messages + del self.tasks_to_iter[(package, task)] + del self.pids_to_task[pid] + +class RunningBuildTreeView (gtk.TreeView): + def __init__ (self): + gtk.TreeView.__init__ (self) + + # The icon that indicates whether we're building or failed. + renderer = gtk.CellRendererPixbuf () + col = gtk.TreeViewColumn ("Status", renderer) + col.add_attribute (renderer, "icon-name", 4) + self.append_column (col) + + # The message of the build. + renderer = gtk.CellRendererText () + col = gtk.TreeViewColumn ("Message", renderer, text=3) + self.append_column (col) + + + diff --git a/bitbake-dev/lib/bb/ui/goggle.py b/bitbake-dev/lib/bb/ui/goggle.py index 651a0449b..0118a356f 100644 --- a/bitbake-dev/lib/bb/ui/goggle.py +++ b/bitbake-dev/lib/bb/ui/goggle.py @@ -22,6 +22,7 @@ import gobject import gtk import threading import bb.ui.uihelper +from bb.ui.crumbs.runningbuild import RunningBuildTreeView, RunningBuild def event_handle_idle_func (eventHandler, build): @@ -33,151 +34,6 @@ def event_handle_idle_func (eventHandler, build): return True -class RunningBuildModel (gtk.TreeStore): - (COL_TYPE, COL_PACKAGE, COL_TASK, COL_MESSAGE, COL_ICON, COL_ACTIVE) = (0, 1, 2, 3, 4, 5) - def __init__ (self): - gtk.TreeStore.__init__ (self, - gobject.TYPE_STRING, - gobject.TYPE_STRING, - gobject.TYPE_STRING, - gobject.TYPE_STRING, - gobject.TYPE_STRING, - gobject.TYPE_BOOLEAN) - -class RunningBuild (gobject.GObject): - __gsignals__ = { - 'build-finished' : (gobject.SIGNAL_RUN_LAST, - gobject.TYPE_NONE, - ()) - } - pids_to_task = {} - tasks_to_iter = {} - - def __init__ (self): - gobject.GObject.__init__ (self) - self.model = RunningBuildModel() - - def handle_event (self, event): - # Handle an event from the event queue, this may result in updating - # the model and thus the UI. Or it may be to tell us that the build - # has finished successfully (or not, as the case may be.) - - parent = None - pid = 0 - package = None - task = None - - # If we have a pid attached to this message/event try and get the - # (package, task) pair for it. If we get that then get the parent iter - # for the message. - if event[1].has_key ('pid'): - pid = event[1]['pid'] - if self.pids_to_task.has_key(pid): - (package, task) = self.pids_to_task[pid] - parent = self.tasks_to_iter[(package, task)] - - if event[0].startswith('bb.msg.Msg'): - # Set a pretty icon for the message based on it's type. - if (event[0].startswith ('bb.msg.MsgWarn')): - icon = "dialog-warning" - elif (event[0].startswith ('bb.msg.MsgErr')): - icon = "dialog-error" - else: - icon = None - - # Ignore the "Running task i of n .." messages - if (event[1]['_message'].startswith ("Running task")): - return - - # Add the message to the tree either at the top level if parent is - # None otherwise as a descendent of a task. - self.model.append (parent, - (event[0].split()[-1], # e.g. MsgWarn, MsgError - package, - task, - event[1]['_message'], - icon, - False)) - elif event[0].startswith('bb.build.TaskStarted'): - (package, task) = (event[1]['_package'], event[1]['_task']) - - # Save out this PID. - self.pids_to_task[pid] = (package,task) - - # Check if we already have this package in our model. If so then - # that can be the parent for the task. Otherwise we create a new - # top level for the package. - if (self.tasks_to_iter.has_key ((package, None))): - parent = self.tasks_to_iter[(package, None)] - else: - parent = self.model.append (None, (None, - package, - None, - "Package: %s" % (package), - None, - False)) - self.tasks_to_iter[(package, None)] = parent - - # Because this parent package now has an active child mark it as - # such. - self.model.set(parent, self.model.COL_ICON, "gtk-execute") - - # Add an entry in the model for this task - i = self.model.append (parent, (None, - package, - task, - "Task: %s" % (task), - None, - False)) - - # Save out the iter so that we can find it when we have a message - # that we need to attach to a task. - self.tasks_to_iter[(package, task)] = i - - # Mark this task as active. - self.model.set(i, self.model.COL_ICON, "gtk-execute") - - elif event[0].startswith('bb.build.Task'): - - if event[0].startswith('bb.build.TaskFailed'): - # Mark the task as failed - i = self.tasks_to_iter[(package, task)] - self.model.set(i, self.model.COL_ICON, "dialog-error") - - # Mark the parent package as failed - i = self.tasks_to_iter[(package, None)] - self.model.set(i, self.model.COL_ICON, "dialog-error") - else: - # Mark the task as inactive - i = self.tasks_to_iter[(package, task)] - self.model.set(i, self.model.COL_ICON, None) - - # Mark the parent package as inactive - i = self.tasks_to_iter[(package, None)] - self.model.set(i, self.model.COL_ICON, None) - - - # Clear the iters and the pids since when the task goes away the - # pid will no longer be used for messages - del self.tasks_to_iter[(package, task)] - del self.pids_to_task[pid] - -class RunningBuildTreeView (gtk.TreeView): - def __init__ (self): - gtk.TreeView.__init__ (self) - - # The icon that indicates whether we're building or failed. - renderer = gtk.CellRendererPixbuf () - col = gtk.TreeViewColumn ("Status", renderer) - col.add_attribute (renderer, "icon-name", 4) - self.append_column (col) - - # The message of the build. - renderer = gtk.CellRendererText () - col = gtk.TreeViewColumn ("Message", renderer, text=3) - self.append_column (col) - - class MainWindow (gtk.Window): def __init__ (self): gtk.Window.__init__ (self, gtk.WINDOW_TOPLEVEL) -- cgit v1.2.3