Beispiel #1
0
    def __init__(self, cfg, updater, ttreeview, ttree_paths, info_bar, theme):

        super(TreeUpdater, self).__init__()

        self.quit = False
        self.autoexpand = True

        self.cfg = cfg
        self.updater = updater
        self.theme = theme
        self.info_bar = info_bar
        self.last_update_time = None
        self.ancestors = {}
        self.descendants = []

        self.autoexpand_states = [
            'queued', 'submitting', 'submitted', 'running', 'failed'
        ]
        self._last_autoexpand_me = []
        self.ttree_paths = ttree_paths  # Dict of paths vs all descendant node states
        self.should_group_families = ("text" not in self.cfg.ungrouped_views)
        self.ttreeview = ttreeview
        # Hierarchy of models: view <- sorted <- filtered <- base model
        self.ttreestore = ttreeview.get_model().get_model().get_model()

        dotm = DotMaker(theme)
        self.dots = {}
        for state in task_state.legal:
            self.dots[state] = dotm.get_icon(state)
        self.dots['empty'] = dotm.get_icon()
Beispiel #2
0
 def _set_key_liststore(self):
     dotm = DotMaker(self._theme, self._dot_size)
     self._key_liststore.clear()
     for state in task_state.legal:
         dot = dotm.get_icon(state)
         self._key_liststore.append([state, dot])
     self._key_liststore.append(['(unknown)', dotm.get_icon('unknown')])
Beispiel #3
0
 def _set_key_liststore(self):
     dotm = DotMaker(self._theme, self._dot_size)
     self._key_liststore.clear()
     for state in task_state.legal:
         dot = dotm.get_icon(state)
         self._key_liststore.append([ state, dot])
     self._key_liststore.append(['(unknown)', dotm.get_icon('unknown')])
Beispiel #4
0
    def __init__(self, cfg, updater, ttreeview, ttree_paths, info_bar, theme):

        super(TreeUpdater, self).__init__()

        self.quit = False
        self.autoexpand = True

        self.cfg = cfg
        self.updater = updater
        self.theme = theme
        self.info_bar = info_bar
        self.last_update_time = None
        self.ancestors = {}
        self.descendants = []

        self.autoexpand_states = ["queued", "submitting", "submitted", "running", "failed"]
        self._last_autoexpand_me = []
        self.ttree_paths = ttree_paths  # Dict of paths vs all descendant node states
        self.should_group_families = "text" not in self.cfg.ungrouped_views
        self.ttreeview = ttreeview
        # Hierarchy of models: view <- sorted <- filtered <- base model
        self.ttreestore = ttreeview.get_model().get_model().get_model()

        dotm = DotMaker(theme)
        self.dots = {}
        for state in task_state.legal:
            self.dots[state] = dotm.get_icon(state)
        self.dots["empty"] = dotm.get_icon()
Beispiel #5
0
    def __init__(self, cfg, updater, treeview, info_bar, theme):

        super(DotUpdater, self).__init__()

        self.quit = False
        self.action_required = False
        self.autoexpand = True
        self.should_hide_headings = False
        self.should_group_families = ("dot" not in cfg.ungrouped_views)
        self.should_transpose_view = False
        self.is_transposed = False

        self.cfg = cfg
        self.updater = updater
        self.theme = theme
        self.info_bar = info_bar
        imagedir = self.cfg.imagedir
        self.last_update_time = None
        self.state_summary = {}
        self.fam_state_summary = {}
        self.ancestors_pruned = {}
        self.descendants = []
        self.filter = ""

        self.led_headings = []
        self.led_treeview = treeview
        self.led_liststore = treeview.get_model()
        self._prev_tooltip_task_id = None
        if hasattr(self.led_treeview, "set_has_tooltip"):
            self.led_treeview.set_has_tooltip(True)
            try:
                self.led_treeview.connect('query-tooltip',
                                          self.on_query_tooltip)
            except TypeError:
                # Lower PyGTK version.
                pass

        self.task_list = []

        # generate task state icons
        dotm = DotMaker(theme)
        self.dots = {}
        for state in task_state.legal:
            self.dots[state] = dotm.get_icon(state)
        self.dots['empty'] = dotm.get_icon()

        self.led_digits_one = []
        self.led_digits_two = []
        self.led_digits_blank = gtk.gdk.pixbuf_new_from_file(
            imagedir + "/digits/one/digit-blank.xpm")
        for i in range(10):
            self.led_digits_one.append(
                gtk.gdk.pixbuf_new_from_file(imagedir + "/digits/one/digit-" +
                                             str(i) + ".xpm"))
            self.led_digits_two.append(
                gtk.gdk.pixbuf_new_from_file(imagedir + "/digits/two/digit-" +
                                             str(i) + ".xpm"))
Beispiel #6
0
    def __init__(self, cfg, updater, treeview, info_bar, theme):

        super(DotUpdater, self).__init__()

        self.quit = False
        self.action_required = False
        self.autoexpand = True
        self.should_hide_headings = False
        self.should_group_families = "dot" not in cfg.ungrouped_views
        self.should_transpose_view = False
        self.is_transposed = False

        self.cfg = cfg
        self.updater = updater
        self.theme = theme
        self.info_bar = info_bar
        imagedir = self.cfg.imagedir
        self.last_update_time = None
        self.state_summary = {}
        self.fam_state_summary = {}
        self.ancestors_pruned = {}
        self.descendants = []
        self.filter = ""

        self.led_headings = []
        self.led_treeview = treeview
        self.led_liststore = treeview.get_model()
        self._prev_tooltip_task_id = None
        if hasattr(self.led_treeview, "set_has_tooltip"):
            self.led_treeview.set_has_tooltip(True)
            try:
                self.led_treeview.connect("query-tooltip", self.on_query_tooltip)
            except TypeError:
                # Lower PyGTK version.
                pass

        self.task_list = []

        # generate task state icons
        dotm = DotMaker(theme)
        self.dots = {}
        for state in task_state.legal:
            self.dots[state] = dotm.get_icon(state)
        self.dots["empty"] = dotm.get_icon()

        self.led_digits_one = []
        self.led_digits_two = []
        self.led_digits_blank = gtk.gdk.pixbuf_new_from_file(imagedir + "/digits/one/digit-blank.xpm")
        for i in range(10):
            self.led_digits_one.append(gtk.gdk.pixbuf_new_from_file(imagedir + "/digits/one/digit-" + str(i) + ".xpm"))
            self.led_digits_two.append(gtk.gdk.pixbuf_new_from_file(imagedir + "/digits/two/digit-" + str(i) + ".xpm"))
Beispiel #7
0
    def __init__(self, cfg, updater, treeview, info_bar, theme ):

        super(DotUpdater, self).__init__()

        self.quit = False
        self.cleared = True
        self.action_required = False
        self.autoexpand = True
        self.should_hide_headings = False
        self.should_group_families = ("dot" not in cfg.ungrouped_views)
        self.should_transpose_view = False
        self.is_transposed = False
        self.defn_order_on = True

        self.cfg = cfg
        self.updater = updater
        self.theme = theme
        self.info_bar = info_bar
        imagedir = self.cfg.imagedir
        self.last_update_time = None
        self.state_summary = {}
        self.fam_state_summary = {}
        self.ancestors_pruned = {}
        self.descendants = []
        self.filter = ""
        self.ctimes = []

        self.led_headings = []
        self.led_treeview = treeview
        self.led_liststore = treeview.get_model()
        self._prev_tooltip_task_id = None
        if hasattr(self.led_treeview, "set_has_tooltip"):
            self.led_treeview.set_has_tooltip(True)
            try:
                self.led_treeview.connect('query-tooltip',
                                          self.on_query_tooltip)
            except TypeError:
                # Lower PyGTK version.
                pass

        self.task_list = []

        # generate task state icons
        dotm = DotMaker( theme )
        self.dots = {}
        for state in task_state.legal:
            self.dots[ state ] = dotm.get_icon( state )
        self.dots['empty'] = dotm.get_icon()
Beispiel #8
0
    def __init__(self, cfg, updater, treeview, info_bar, theme, dot_size):

        super(DotUpdater, self).__init__()

        self.quit = False
        self.cleared = True
        self.action_required = False
        self.autoexpand = True
        self.should_hide_headings = False
        self.should_group_families = ("dot" not in cfg.ungrouped_views)
        self.should_transpose_view = False
        self.is_transposed = False
        self.defn_order_on = True

        self.cfg = cfg
        self.updater = updater
        self.theme = theme
        self.info_bar = info_bar
        imagedir = self.cfg.imagedir
        self.last_update_time = None
        self.state_summary = {}
        self.fam_state_summary = {}
        self.ancestors_pruned = {}
        self.descendants = []
        self.filter = ""
        self.point_strings = []

        self.led_headings = []
        self.led_treeview = treeview
        self.led_liststore = treeview.get_model()
        self._prev_tooltip_task_id = None
        if hasattr(self.led_treeview, "set_has_tooltip"):
            self.led_treeview.set_has_tooltip(True)
            try:
                self.led_treeview.connect('query-tooltip',
                                          self.on_query_tooltip)
            except TypeError:
                # Lower PyGTK version.
                pass

        self.task_list = []

        # generate task state icons
        dotm = DotMaker(theme, size=dot_size)
        self.dots = dotm.get_dots()
Beispiel #9
0
    def __init__(self, cfg, treeview, info_bar, theme ):

        super(lupdater, self).__init__()

        self.quit = False
        self.autoexpand = True
        self.should_hide_headings = False
        self.should_group_families = False

        self.cfg = cfg
        self.theme = theme
        self.info_bar = info_bar
        imagedir = self.cfg.imagedir

        self.state_summary = {}
        self.global_summary = {}
        self.stop_summary = None
        self.families = []
        self.god = None
        self.mode = "waiting..."
        self.dt = "waiting..."
        self.status = None
        self.poll_schd = PollSchd()
        self.filter = ""

        self.led_treeview = treeview
        self.led_liststore = treeview.get_model()
        self._prev_tooltip_task_id = None

        self.reconnect()

        # generate task state icons
        dotm = DotMaker( theme )
        self.dots = {}
        for state in task_state.legal:
            self.dots[ state ] = dotm.get_icon( state )
        self.dots['empty'] = dotm.get_icon()

        self.led_digits_one = []
        self.led_digits_two = []
        self.led_digits_blank = gtk.gdk.pixbuf_new_from_file( imagedir + "/digits/one/digit-blank.xpm" )
        for i in range(10):
            self.led_digits_one.append( gtk.gdk.pixbuf_new_from_file( imagedir + "/digits/one/digit-" + str(i) + ".xpm" ))
            self.led_digits_two.append( gtk.gdk.pixbuf_new_from_file( imagedir + "/digits/two/digit-" + str(i) + ".xpm" ))
Beispiel #10
0
    def __init__(self, cfg, updater, ttreeview, ttree_paths, info_bar, theme ):

        super(TreeUpdater, self).__init__()

        self.action_required = False
        self.quit = False
        self.cleared = True
        self.autoexpand = True

        self.count = 0

        self.cfg = cfg
        self.updater = updater
        self.theme = theme
        self.info_bar = info_bar
        self.last_update_time = None
        self.ancestors = {}
        self.descendants = []

        self.autoexpand_states = [ 'queued', 'ready', 'submitted', 'running', 'failed' ]
        self._last_autoexpand_me = []
        self.ttree_paths = ttree_paths  # Dict of paths vs all descendant node states
        self.should_group_families = ("text" not in self.cfg.ungrouped_views)
        self.ttreeview = ttreeview
        # Hierarchy of models: view <- sorted <- filtered <- base model
        self.ttreestore = ttreeview.get_model().get_model().get_model()
        self._prev_tooltip_task_id = None
        if hasattr(self.ttreeview, "set_has_tooltip"):
            self.ttreeview.set_has_tooltip(True)
            try:
                self.ttreeview.connect('query-tooltip',
                                       self.on_query_tooltip)
            except TypeError:
                # Lower PyGTK version.
                pass

        dotm = DotMaker( theme )
        self.dots = {}
        for state in task_state.legal:
            self.dots[ state ] = dotm.get_icon( state )
        self.dots['empty'] = dotm.get_icon()
Beispiel #11
0
    def __init__(self, cfg, updater, ttreeview, ttree_paths, info_bar, theme, dot_size):

        super(TreeUpdater, self).__init__()

        self.action_required = False
        self.quit = False
        self.cleared = True
        self.autoexpand = True

        self.count = 0

        self.cfg = cfg
        self.updater = updater
        self.info_bar = info_bar
        self.last_update_time = None
        self.ancestors = {}
        self.descendants = []

        self.autoexpand_states = [ 'queued', 'ready', 'submitted', 'running', 'failed' ]
        self._last_autoexpand_me = []
        self.ttree_paths = ttree_paths  # Dict of paths vs all descendant node states
        self.should_group_families = ("text" not in self.cfg.ungrouped_views)
        self.ttreeview = ttreeview
        # Hierarchy of models: view <- sorted <- filtered <- base model
        self.ttreestore = ttreeview.get_model().get_model().get_model()
        self._prev_tooltip_task_id = None
        if hasattr(self.ttreeview, "set_has_tooltip"):
            self.ttreeview.set_has_tooltip(True)
            try:
                self.ttreeview.connect('query-tooltip',
                                       self.on_query_tooltip)
            except TypeError:
                # Lower PyGTK version.
                pass

        # Cache the latest ETC calculation for active ids.
        self._id_tetc_cache = {}

        # Generate task state icons.
        dotm = DotMaker(theme, size=dot_size)
        self.dots = dotm.get_dots()
Beispiel #12
0
 def __init__(self,
              hosts,
              dot_hbox,
              gcylc_image,
              is_compact,
              owner=None,
              poll_interval=None):
     self.quit = True
     self.dot_hbox = dot_hbox
     self.gcylc_image = gcylc_image
     self.is_compact = is_compact
     self._set_gcylc_image_tooltip()
     self.gcylc_image.set_sensitive(False)
     self.theme_name = gcfg.get(['use theme'])
     self.theme = gcfg.get(['themes', self.theme_name])
     self.dots = DotMaker(self.theme)
     self.statuses = {}
     self.stop_summaries = {}
     self._set_exception_hook()
     super(SummaryPanelAppletUpdater,
           self).__init__(hosts, owner=owner, poll_interval=poll_interval)
Beispiel #13
0
    def __init__(self, cfg, ttreeview, ttree_paths, info_bar, theme ):

        super(tupdater, self).__init__()

        self.quit = False
        self.autoexpand = True

        self.cfg = cfg
        self.theme = theme
        self.info_bar = info_bar

        self.state_summary = {}
        self.global_summary = {}
        self.fam_state_summary = {}
        self.stop_summary = None
        self.families = []
        self.god = None
        self.mode = "waiting..."
        self.dt = "waiting..."
        self.status = None
        self.poll_schd = PollSchd()

        self.autoexpand_states = [ 'submitted', 'running', 'failed', 'held' ]
        self._last_autoexpand_me = []
        self.ttree_paths = ttree_paths  # Dict of paths vs all descendant node states
        self.should_group_families = False
        self.ttreeview = ttreeview
        # Hierarchy of models: view <- sorted <- filtered <- base model
        self.ttreestore = ttreeview.get_model().get_model().get_model()

        dotm = DotMaker( theme )
        self.dots = {}
        for state in task_state.legal:
            self.dots[ state ] = dotm.get_icon( state )
        self.dots['empty'] = dotm.get_icon()

        self.reconnect()
Beispiel #14
0
 def __init__(self, hosts, dot_hbox, gcylc_image, is_compact, owner=None,
              poll_interval=None):
     self.quit = True
     self.dot_hbox = dot_hbox
     self.gcylc_image = gcylc_image
     self.is_compact = is_compact
     self._set_gcylc_image_tooltip()
     self.gcylc_image.set_sensitive(False)
     self.theme_name = gcfg.get( ['use theme'] )
     self.theme = gcfg.get( ['themes', self.theme_name] )
     self.dots = DotMaker(self.theme)
     self.statuses = {}
     self.stop_summaries = {}
     self._set_exception_hook()
     super(SummaryPanelAppletUpdater, self).__init__(
                           hosts, owner=owner, poll_interval=poll_interval)
Beispiel #15
0
 def _set_theme(self, new_theme_name):
     self.theme_name = new_theme_name
     self.theme = gcfg.get( ['themes',self.theme_name] )
     self.dots = DotMaker(self.theme)
Beispiel #16
0
    def __init__(self, hosts=None, owner=None, poll_interval=None):
        gobject.threads_init()
        set_exception_hook_dialog("cylc gsummary")
        setup_icons()
        if not hosts:
            try:
                hosts = sitecfg.get( ["suite host scanning","hosts"] )
            except KeyError:
                hosts = ["localhost"]
        self.hosts = hosts
        if owner is None:
            owner = user
        self.owner = owner
        self.window = gtk.Window()
        self.window.set_title("cylc gsummary")
        self.window.set_icon(get_icon())
        self.vbox = gtk.VBox()
        self.vbox.show()

        self.theme_name = gcfg.get( ['use theme'] )
        self.theme = gcfg.get( ['themes', self.theme_name] )

        self.dots = DotMaker(self.theme)
        suite_treemodel = gtk.TreeStore(*([str, str, bool, str, int] +
            [str] * 20))
        self._prev_tooltip_location_id = None
        self.suite_treeview = gtk.TreeView(suite_treemodel)

        # Construct the host column.
        host_name_column = gtk.TreeViewColumn("Host")
        cell_text_host = gtk.CellRendererText()
        host_name_column.pack_start(cell_text_host, expand=False)
        host_name_column.set_cell_data_func(
                  cell_text_host, self._set_cell_text_host)
        host_name_column.set_sort_column_id(0)
        host_name_column.set_visible(False)

        # Construct the suite name column.
        suite_name_column = gtk.TreeViewColumn("Suite")
        cell_text_name = gtk.CellRendererText()
        suite_name_column.pack_start(cell_text_name, expand=False)
        suite_name_column.set_cell_data_func(
                   cell_text_name, self._set_cell_text_name)
        suite_name_column.set_sort_column_id(1)

        # Construct the suite title column.
        suite_title_column = gtk.TreeViewColumn("Title")
        cell_text_title = gtk.CellRendererText()
        suite_title_column.pack_start(cell_text_title, expand=False)
        suite_title_column.set_cell_data_func(
                   cell_text_title, self._set_cell_text_title)
        suite_title_column.set_sort_column_id(3)
        suite_title_column.set_visible(False)

        # Construct the update time column.
        time_column = gtk.TreeViewColumn("Updated")
        cell_text_time = gtk.CellRendererText()
        time_column.pack_start(cell_text_time, expand=False)
        time_column.set_cell_data_func(
                    cell_text_time, self._set_cell_text_time)
        time_column.set_sort_column_id(4)
        time_column.set_visible(False)

        # Construct the status column.
        status_column = gtk.TreeViewColumn("Status")
        status_column.set_sort_column_id(5)
        for i in range(5, 25):
            cell_pixbuf_state = gtk.CellRendererPixbuf()
            status_column.pack_start(cell_pixbuf_state, expand=False)
            status_column.set_cell_data_func(
                   cell_pixbuf_state, self._set_cell_pixbuf_state, i)

        self.suite_treeview.append_column(host_name_column)
        self.suite_treeview.append_column(suite_name_column)
        self.suite_treeview.append_column(suite_title_column)
        self.suite_treeview.append_column(time_column)
        self.suite_treeview.append_column(status_column)
        self.suite_treeview.show()
        if hasattr(self.suite_treeview, "set_has_tooltip"):
            self.suite_treeview.set_has_tooltip(True)
            try:
                self.suite_treeview.connect('query-tooltip',
                                            self._on_query_tooltip)
            except TypeError:
                # Lower PyGTK version.
                pass
        self.suite_treeview.connect("button-press-event",
                                    self._on_button_press_event)
        scrolled_window = gtk.ScrolledWindow()
        scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
                                   gtk.POLICY_AUTOMATIC)
        scrolled_window.add(self.suite_treeview)
        scrolled_window.show()
        self.vbox.pack_start(scrolled_window, expand=True, fill=True)
        self.updater = SummaryAppUpdater(self.hosts, suite_treemodel,
                                         owner=self.owner,
                                         poll_interval=poll_interval)
        self.updater.start()
        self.window.add(self.vbox)
        self.window.connect("destroy", self._on_destroy_event)
        self.window.set_default_size(200, 100)
        self.suite_treeview.grab_focus()
        self.window.show()
Beispiel #17
0
class SummaryApp(object):

    """Summarize running suite statuses for a given set of hosts."""

    def __init__(self, hosts=None, owner=None, poll_interval=None):
        gobject.threads_init()
        set_exception_hook_dialog("cylc gsummary")
        setup_icons()
        if not hosts:
            try:
                hosts = sitecfg.get( ["suite host scanning","hosts"] )
            except KeyError:
                hosts = ["localhost"]
        self.hosts = hosts
        if owner is None:
            owner = user
        self.owner = owner
        self.window = gtk.Window()
        self.window.set_title("cylc gsummary")
        self.window.set_icon(get_icon())
        self.vbox = gtk.VBox()
        self.vbox.show()

        self.theme_name = gcfg.get( ['use theme'] )
        self.theme = gcfg.get( ['themes', self.theme_name] )

        self.dots = DotMaker(self.theme)
        suite_treemodel = gtk.TreeStore(*([str, str, bool, str, int] +
            [str] * 20))
        self._prev_tooltip_location_id = None
        self.suite_treeview = gtk.TreeView(suite_treemodel)

        # Construct the host column.
        host_name_column = gtk.TreeViewColumn("Host")
        cell_text_host = gtk.CellRendererText()
        host_name_column.pack_start(cell_text_host, expand=False)
        host_name_column.set_cell_data_func(
                  cell_text_host, self._set_cell_text_host)
        host_name_column.set_sort_column_id(0)
        host_name_column.set_visible(False)

        # Construct the suite name column.
        suite_name_column = gtk.TreeViewColumn("Suite")
        cell_text_name = gtk.CellRendererText()
        suite_name_column.pack_start(cell_text_name, expand=False)
        suite_name_column.set_cell_data_func(
                   cell_text_name, self._set_cell_text_name)
        suite_name_column.set_sort_column_id(1)

        # Construct the suite title column.
        suite_title_column = gtk.TreeViewColumn("Title")
        cell_text_title = gtk.CellRendererText()
        suite_title_column.pack_start(cell_text_title, expand=False)
        suite_title_column.set_cell_data_func(
                   cell_text_title, self._set_cell_text_title)
        suite_title_column.set_sort_column_id(3)
        suite_title_column.set_visible(False)

        # Construct the update time column.
        time_column = gtk.TreeViewColumn("Updated")
        cell_text_time = gtk.CellRendererText()
        time_column.pack_start(cell_text_time, expand=False)
        time_column.set_cell_data_func(
                    cell_text_time, self._set_cell_text_time)
        time_column.set_sort_column_id(4)
        time_column.set_visible(False)

        # Construct the status column.
        status_column = gtk.TreeViewColumn("Status")
        status_column.set_sort_column_id(5)
        for i in range(5, 25):
            cell_pixbuf_state = gtk.CellRendererPixbuf()
            status_column.pack_start(cell_pixbuf_state, expand=False)
            status_column.set_cell_data_func(
                   cell_pixbuf_state, self._set_cell_pixbuf_state, i)

        self.suite_treeview.append_column(host_name_column)
        self.suite_treeview.append_column(suite_name_column)
        self.suite_treeview.append_column(suite_title_column)
        self.suite_treeview.append_column(time_column)
        self.suite_treeview.append_column(status_column)
        self.suite_treeview.show()
        if hasattr(self.suite_treeview, "set_has_tooltip"):
            self.suite_treeview.set_has_tooltip(True)
            try:
                self.suite_treeview.connect('query-tooltip',
                                            self._on_query_tooltip)
            except TypeError:
                # Lower PyGTK version.
                pass
        self.suite_treeview.connect("button-press-event",
                                    self._on_button_press_event)
        scrolled_window = gtk.ScrolledWindow()
        scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
                                   gtk.POLICY_AUTOMATIC)
        scrolled_window.add(self.suite_treeview)
        scrolled_window.show()
        self.vbox.pack_start(scrolled_window, expand=True, fill=True)
        self.updater = SummaryAppUpdater(self.hosts, suite_treemodel,
                                         owner=self.owner,
                                         poll_interval=poll_interval)
        self.updater.start()
        self.window.add(self.vbox)
        self.window.connect("destroy", self._on_destroy_event)
        self.window.set_default_size(200, 100)
        self.suite_treeview.grab_focus()
        self.window.show()

    def _on_button_press_event(self, treeview, event):
        # DISPLAY MENU ONLY ON RIGHT CLICK ONLY

        if (event.type != gtk.gdk._2BUTTON_PRESS and
            event.button != 3):
            return False

        treemodel = treeview.get_model()

        x = int(event.x)
        y = int(event.y)
        time = event.time
        pth = treeview.get_path_at_pos(x, y)

        suite_host_tuples = []

        if pth is not None:
            # Add a gcylc launcher item.
            path, col, cellx, celly = pth

            iter_ = treemodel.get_iter(path)
            host, suite = treemodel.get(iter_, 0, 1)
            suite_host_tuples.append((suite, host))

        if event.type == gtk.gdk._2BUTTON_PRESS:
            if suite_host_tuples:
                launch_gcylc(host, suite, owner=self.owner)
            return False

        has_stopped_suites = bool(self.updater.stop_summaries)

        view_item = gtk.ImageMenuItem("View Column...")
        img = gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_MENU)
        view_item.set_image(img)
        view_item.show()
        view_menu = gtk.Menu()
        view_item.set_submenu(view_menu)
        for column_index, column in enumerate(treeview.get_columns()):
            name = column.get_title()
            is_visible = column.get_visible()
            column_item = gtk.CheckMenuItem(name.replace("_", "__"))
            column_item._connect_args = (column_index, is_visible)
            column_item.set_active(is_visible)
            column_item.connect("toggled", self._on_toggle_column_visible)
            column_item.show()
            view_menu.append(column_item)

        menu = get_summary_menu(suite_host_tuples,
                                self.theme_name,
                                self._set_theme,
                                has_stopped_suites,
                                self.updater.clear_stopped_suites,
                                self.hosts,
                                self.updater.set_hosts,
                                self.updater.update_now,
                                self.updater.start,
                                program_name="cylc gsummary",
                                extra_items=[view_item],
                                owner=self.owner)
        menu.popup( None, None, None, event.button, event.time )
        return False

    def _on_destroy_event(self, widget):
        self.updater.quit = True
        gtk.main_quit()
        return False

    def _on_query_tooltip(self, widget, x, y, kbd_ctx, tooltip):
        """Handle a tooltip creation request."""
        tip_context = self.suite_treeview.get_tooltip_context(x, y, kbd_ctx)
        if tip_context is None:
            self._prev_tooltip_location_id = None
            return False
        x, y = self.suite_treeview.convert_widget_to_bin_window_coords(x, y)
        path, column, cell_x, cell_y = self.suite_treeview.get_path_at_pos(
                                                                    x, y)
        model = self.suite_treeview.get_model()
        iter_ = model.get_iter(path)
        host = model.get_value(iter_, 0)
        suite = model.get_value(iter_, 1)
        update_time = model.get_value(iter_, 4)

        location_id = (host, suite, update_time, column.get_title())
        if location_id != self._prev_tooltip_location_id:
            self._prev_tooltip_location_id = location_id
            tooltip.set_text(None)
            return False
        if column.get_title() in ["Host", "Suite"]:
            tooltip.set_text(suite + " - " + host)
            return True
        if column.get_title() == "Updated":
            time_object = datetime.datetime.fromtimestamp(update_time)
            text = "Info retrieved at " + time_object.isoformat()
            tooltip.set_text(text)
            return True
        if column.get_title() != "Status":
            tooltip.set_text(None)
            return False
        state_texts = []
        for i in range(5, 25):
            state_text = model.get_value(iter_, i)
            if state_text is None:
                break
            status, number = state_text.rsplit(" ", 1)
            state_texts.append(number + " " + status)
        text = "Tasks: " + ", ".join(state_texts)
        tooltip.set_text(text)
        return True

    def _on_toggle_column_visible(self, menu_item):
        column_index, is_visible = menu_item._connect_args
        column = self.suite_treeview.get_columns()[column_index]
        column.set_visible(not is_visible)
        return False

    def _set_cell_pixbuf_state(self, column, cell, model, iter_, index):
        state_info = model.get_value(iter_, index)
        if state_info is None:
            cell.set_property("pixbuf", None)
            cell.set_property("visible", False)
            return
        is_stopped = model.get_value(iter_, 2)
        state, num_tasks = state_info.rsplit(" ", 1)
        icon = self.dots.get_icon(state, is_stopped=is_stopped)
        cell.set_property("pixbuf", icon)
        cell.set_property("visible", True)

    def _set_cell_text_host(self, column, cell, model, iter_):
        host = model.get_value(iter_, 0)
        is_stopped = model.get_value(iter_, 2)
        cell.set_property("sensitive", not is_stopped)
        cell.set_property("text", host)

    def _set_cell_text_name(self, column, cell, model, iter_):
        name = model.get_value(iter_, 1)
        is_stopped = model.get_value(iter_, 2)
        cell.set_property("sensitive", not is_stopped)
        cell.set_property("text", name)

    def _set_cell_text_title(self, column, cell, model, iter_):
        title = model.get_value(iter_, 3)
        is_stopped = model.get_value(iter_, 2)
        cell.set_property("sensitive", not is_stopped)
        cell.set_property("text", title)

    def _set_cell_text_time(self, column, cell, model, iter_):
        update_time = model.get_value(iter_, 4)
        time_object = datetime.datetime.fromtimestamp(update_time)
        time_string = time_object.strftime("%H:%M:%S")
        is_stopped = model.get_value(iter_, 2)
        cell.set_property("sensitive", not is_stopped)
        cell.set_property("text", time_string)

    def _set_theme(self, new_theme_name):
        self.theme_name = new_theme_name
        self.theme = gcfg.get( ['themes',self.theme_name] )
        self.dots = DotMaker(self.theme)

    def _set_tooltip(self, widget, text):
        tooltip = gtk.Tooltips()
        tooltip.enable()
        tooltip.set_tip(widget, text)
Beispiel #18
0
 def _set_key_liststore( self ):
     dotm = DotMaker( self._theme )
     self._key_liststore.clear()
     for state in task_state.legal:
         dot = dotm.get_icon( state )
         self._key_liststore.append( [ state, dot ] )
Beispiel #19
0
 def _set_theme(self, new_theme_name):
     self.theme_name = new_theme_name
     self.theme = gcfg.get(['themes', self.theme_name])
     self.dots = DotMaker(self.theme)
Beispiel #20
0
class SummaryPanelAppletUpdater(BaseSummaryTimeoutUpdater):
    """Update the summary panel applet - subclass of gsummary equivalent."""

    IDLE_STOPPED_TIME = 3600  # 1 hour.
    MAX_INDIVIDUAL_SUITES = 5

    def __init__(self,
                 hosts,
                 dot_hbox,
                 gcylc_image,
                 is_compact,
                 owner=None,
                 poll_interval=None):
        self.quit = True
        self.dot_hbox = dot_hbox
        self.gcylc_image = gcylc_image
        self.is_compact = is_compact
        self._set_gcylc_image_tooltip()
        self.gcylc_image.set_sensitive(False)
        self.theme_name = gcfg.get(['use theme'])
        self.theme = gcfg.get(['themes', self.theme_name])
        self.dots = DotMaker(self.theme)
        self.statuses = {}
        self.stop_summaries = {}
        self._set_exception_hook()
        super(SummaryPanelAppletUpdater,
              self).__init__(hosts, owner=owner, poll_interval=poll_interval)

    def clear_stopped_suites(self):
        """Clear stopped suite information that may have built up."""
        self.stop_summaries.clear()
        gobject.idle_add(self.update)

    def start(self):
        self.gcylc_image.set_sensitive(True)
        super(SummaryPanelAppletUpdater, self).start()
        self._set_gcylc_image_tooltip()

    def stop(self):
        self.gcylc_image.set_sensitive(False)
        super(SummaryPanelAppletUpdater, self).stop()
        self._set_gcylc_image_tooltip()

    def launch_context_menu(self,
                            event,
                            suite_host_tuples=None,
                            extra_items=None):
        has_stopped_suites = bool(self.stop_summaries)

        if suite_host_tuples is None:
            suite_host_tuples = []

        if extra_items is None:
            extra_items = []

        gsummary_item = gtk.ImageMenuItem("Launch cylc gsummary")
        img = gtk.image_new_from_stock("gcylc", gtk.ICON_SIZE_MENU)
        gsummary_item.set_image(img)
        gsummary_item.show()
        gsummary_item.connect("button-press-event",
                              self._on_button_press_event_gsummary)

        extra_items.append(gsummary_item)

        menu = get_summary_menu(suite_host_tuples,
                                self.theme_name,
                                self._set_theme,
                                has_stopped_suites,
                                self.clear_stopped_suites,
                                self.hosts,
                                self.set_hosts,
                                self.update_now,
                                self.start,
                                program_name="cylc gpanel",
                                extra_items=extra_items,
                                owner=self.owner,
                                is_stopped=self.quit)
        menu.popup(None, None, None, event.button, event.time)
        return False

    def update(self, update_time=None):
        """Update the Applet."""
        suite_host_tuples = []
        statuses = copy.deepcopy(self.statuses)
        stop_summaries = copy.deepcopy(self.stop_summaries)
        for host in self.hosts:
            suites = (statuses.get(host, {}).keys() +
                      stop_summaries.get(host, {}).keys())
            for suite in suites:
                suite_host_tuples.append((suite, host))
        suite_host_tuples.sort()
        for child in self.dot_hbox.get_children():
            self.dot_hbox.remove(child)
        number_mode = (not self.is_compact
                       and len(suite_host_tuples) > self.MAX_INDIVIDUAL_SUITES)
        suite_statuses = {}
        compact_suite_statuses = []
        for suite, host in suite_host_tuples:
            if suite in statuses.get(host, {}):
                status_map = statuses[host][suite]
                is_stopped = False
            else:
                info = stop_summaries[host][suite]
                status_map, suite_time = info
                is_stopped = True
            status = extract_group_state(status_map.keys(),
                                         is_stopped=is_stopped)
            if number_mode:
                suite_statuses.setdefault(is_stopped, {})
                suite_statuses[is_stopped].setdefault(status, [])
                suite_statuses[is_stopped][status].append(
                    (suite, host, status_map.items()))
            elif self.is_compact:
                compact_suite_statuses.append(
                    (suite, host, status, status_map.items(), is_stopped))
            else:
                self._add_image_box([(suite, host, status, status_map.items(),
                                      is_stopped)])
        if number_mode:
            for is_stopped in sorted(suite_statuses.keys()):
                statuses = suite_statuses[is_stopped].items()
                statuses.sort(lambda x, y: cmp(len(y[1]), len(x[1])))
                for status, suite_host_states_tuples in statuses:
                    label = gtk.Label(str(len(suite_host_states_tuples)) + ":")
                    label.show()
                    self.dot_hbox.pack_start(label, expand=False, fill=False)
                    suite_info_tuples = []
                    for suite, host, task_states in suite_host_states_tuples:
                        suite_info_tuples.append(
                            (suite, host, status, task_states, is_stopped))
                    self._add_image_box(suite_info_tuples)
        if self.is_compact:
            if not compact_suite_statuses:
                # No suites running or stopped.
                self.gcylc_image.show()
                return False
            self.gcylc_image.hide()
            self._add_image_box(compact_suite_statuses)
        return False

    def _add_image_box(self, suite_host_info_tuples):
        image_eb = gtk.EventBox()
        image_eb.show()
        is_all_stopped = False
        running_status_list = []
        status_list = []
        suite_host_tuples = []
        for info_tuple in suite_host_info_tuples:
            suite, host, status, task_states, is_stopped = info_tuple
            suite_host_tuples.append((suite, host))
            if not is_stopped:
                running_status_list.append(status)
            status_list.append(status)
        if running_status_list:
            status = extract_group_state(running_status_list, is_stopped=False)
            image = self.dots.get_image(status, is_stopped=False)
        else:
            status = extract_group_state(status_list, is_stopped=True)
            image = self.dots.get_image(status, is_stopped=True)
        image.show()
        image_eb.add(image)
        image_eb._connect_args = suite_host_tuples
        image_eb.connect("button-press-event", self._on_button_press_event)

        text_format = "%s - %s - %s"
        long_text_format = text_format + "\n    Tasks: %s\n"
        text = ""
        tip_vbox = gtk.VBox()  # Only used in PyGTK 2.12+
        tip_vbox.show()
        for info_tuple in suite_host_info_tuples:
            suite, host, status, task_states, is_stopped = info_tuple
            task_states.sort(lambda x, y: cmp(len(y[1]), len(x[1])))
            tip_hbox = gtk.HBox()
            tip_hbox.show()
            state_info = []
            for state_name, tasks in task_states:
                state_info.append(str(len(tasks)) + " " + state_name)
                image = self.dots.get_image(state_name, is_stopped=is_stopped)
                image.show()
                tip_hbox.pack_start(image, expand=False, fill=False)
            states_text = ", ".join(state_info)
            if status is None:
                suite_summary = "?"
            else:
                suite_summary = status
            if is_stopped:
                suite_summary = "stopped with " + suite_summary
            tip_label = gtk.Label(text_format % (suite, suite_summary, host))
            tip_label.show()
            tip_hbox.pack_start(tip_label, expand=False, fill=False, padding=5)
            tip_vbox.pack_start(tip_hbox, expand=False, fill=False)
            text += long_text_format % (suite, suite_summary, host,
                                        states_text)
        text = text.rstrip()
        if hasattr(gtk, "Tooltip"):
            image_eb.set_has_tooltip(True)
            image_eb.connect("query-tooltip", self._on_img_tooltip_query,
                             tip_vbox)
        else:
            self._set_tooltip(image_eb, text)
        self.dot_hbox.pack_start(image_eb, expand=False, fill=False, padding=1)

    def _on_button_press_event(self, widget, event):
        if event.button == 1:
            self.launch_context_menu(event,
                                     suite_host_tuples=widget._connect_args)
        return False

    def _on_button_press_event_gsummary(self, widget, event):
        launch_gsummary(hosts=self.hosts, owner=self.owner)

    def _on_img_tooltip_query(self, widget, x, y, kbd, tooltip, tip_widget):
        tooltip.set_custom(tip_widget)
        return True

    def _set_exception_hook(self):
        # Handle an uncaught exception.
        old_hook = sys.excepthook
        sys.excepthook = (
            lambda *a: self._handle_exception(*a, old_hook=old_hook))

    def _handle_exception(self, e_type, e_value, e_traceback, old_hook=None):
        self.gcylc_image.set_from_stock(gtk.STOCK_DIALOG_ERROR,
                                        gtk.ICON_SIZE_MENU)
        exc_lines = traceback.format_exception(e_type, e_value, e_traceback)
        exc_text = "".join(exc_lines)
        info = "cylc gpanel has a problem.\n\n%s" % exc_text
        self._set_tooltip(self.gcylc_image, info.rstrip())
        if old_hook is not None:
            old_hook(exception_class, exception, trace)

    def _set_gcylc_image_tooltip(self):
        if self.quit:
            self._set_tooltip(self.gcylc_image, "Cylc Applet - Off")
        else:
            self._set_tooltip(self.gcylc_image, "Cylc Applet - Active")

    def _set_theme(self, new_theme_name):
        self.theme_name = new_theme_name
        self.theme = gcfg.get(['themes', self.theme_name])
        self.dots = DotMaker(self.theme)

    def _set_tooltip(self, widget, text):
        tooltip = gtk.Tooltips()
        tooltip.enable()
        tooltip.set_tip(widget, text)
Beispiel #21
0
 def _set_theme(self, new_theme_name):
     self.theme_name = new_theme_name
     self.theme = self.usercfg['themes'][self.theme_name]
     self.dots = DotMaker(self.theme)
Beispiel #22
0
    def __init__(self, hosts=None, owner=None, poll_interval=None):
        gobject.threads_init()
        set_exception_hook_dialog("cylc gsummary")
        setup_icons()
        if not hosts:
            try:
                hosts = GLOBAL_CFG.get( ["suite host scanning","hosts"] )
            except KeyError:
                hosts = ["localhost"]
        self.hosts = hosts
        if owner is None:
            owner = user
        self.owner = owner
        self.window = gtk.Window()
        self.window.set_title("cylc gsummary")
        self.window.set_icon(get_icon())
        self.vbox = gtk.VBox()
        self.vbox.show()

        self.theme_name = gcfg.get( ['use theme'] )
        self.theme = gcfg.get( ['themes', self.theme_name] )

        self.dots = DotMaker(self.theme)
        suite_treemodel = gtk.TreeStore(*([str, str, bool, str, int] +
            [str] * 20))
        self._prev_tooltip_location_id = None
        self.suite_treeview = gtk.TreeView(suite_treemodel)

        # Construct the host column.
        host_name_column = gtk.TreeViewColumn("Host")
        cell_text_host = gtk.CellRendererText()
        host_name_column.pack_start(cell_text_host, expand=False)
        host_name_column.set_cell_data_func(
                  cell_text_host, self._set_cell_text_host)
        host_name_column.set_sort_column_id(0)
        host_name_column.set_visible(False)

        # Construct the suite name column.
        suite_name_column = gtk.TreeViewColumn("Suite")
        cell_text_name = gtk.CellRendererText()
        suite_name_column.pack_start(cell_text_name, expand=False)
        suite_name_column.set_cell_data_func(
                   cell_text_name, self._set_cell_text_name)
        suite_name_column.set_sort_column_id(1)

        # Construct the suite title column.
        suite_title_column = gtk.TreeViewColumn("Title")
        cell_text_title = gtk.CellRendererText()
        suite_title_column.pack_start(cell_text_title, expand=False)
        suite_title_column.set_cell_data_func(
                   cell_text_title, self._set_cell_text_title)
        suite_title_column.set_sort_column_id(3)
        suite_title_column.set_visible(False)

        # Construct the update time column.
        time_column = gtk.TreeViewColumn("Updated")
        cell_text_time = gtk.CellRendererText()
        time_column.pack_start(cell_text_time, expand=False)
        time_column.set_cell_data_func(
                    cell_text_time, self._set_cell_text_time)
        time_column.set_sort_column_id(4)
        time_column.set_visible(False)

        # Construct the status column.
        status_column = gtk.TreeViewColumn("Status")
        status_column.set_sort_column_id(5)
        for i in range(5, 25):
            cell_pixbuf_state = gtk.CellRendererPixbuf()
            status_column.pack_start(cell_pixbuf_state, expand=False)
            status_column.set_cell_data_func(
                   cell_pixbuf_state, self._set_cell_pixbuf_state, i)

        self.suite_treeview.append_column(host_name_column)
        self.suite_treeview.append_column(suite_name_column)
        self.suite_treeview.append_column(suite_title_column)
        self.suite_treeview.append_column(time_column)
        self.suite_treeview.append_column(status_column)
        self.suite_treeview.show()
        if hasattr(self.suite_treeview, "set_has_tooltip"):
            self.suite_treeview.set_has_tooltip(True)
            try:
                self.suite_treeview.connect('query-tooltip',
                                            self._on_query_tooltip)
            except TypeError:
                # Lower PyGTK version.
                pass
        self.suite_treeview.connect("button-press-event",
                                    self._on_button_press_event)
        scrolled_window = gtk.ScrolledWindow()
        scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
                                   gtk.POLICY_AUTOMATIC)
        scrolled_window.add(self.suite_treeview)
        scrolled_window.show()
        self.vbox.pack_start(scrolled_window, expand=True, fill=True)
        self.updater = SummaryAppUpdater(self.hosts, suite_treemodel,
                                         owner=self.owner,
                                         poll_interval=poll_interval)
        self.updater.start()
        self.window.add(self.vbox)
        self.window.connect("destroy", self._on_destroy_event)
        self.window.set_default_size(200, 100)
        self.suite_treeview.grab_focus()
        self.window.show()
Beispiel #23
0
class SummaryApp(object):

    """Summarize running suite statuses for a given set of hosts."""

    def __init__(self, hosts=None, owner=None, poll_interval=None):
        gobject.threads_init()
        set_exception_hook_dialog("cylc gsummary")
        setup_icons()
        if not hosts:
            try:
                hosts = GLOBAL_CFG.get( ["suite host scanning","hosts"] )
            except KeyError:
                hosts = ["localhost"]
        self.hosts = hosts
        if owner is None:
            owner = user
        self.owner = owner
        self.window = gtk.Window()
        self.window.set_title("cylc gsummary")
        self.window.set_icon(get_icon())
        self.vbox = gtk.VBox()
        self.vbox.show()

        self.theme_name = gcfg.get( ['use theme'] )
        self.theme = gcfg.get( ['themes', self.theme_name] )

        self.dots = DotMaker(self.theme)
        suite_treemodel = gtk.TreeStore(*([str, str, bool, str, int] +
            [str] * 20))
        self._prev_tooltip_location_id = None
        self.suite_treeview = gtk.TreeView(suite_treemodel)

        # Construct the host column.
        host_name_column = gtk.TreeViewColumn("Host")
        cell_text_host = gtk.CellRendererText()
        host_name_column.pack_start(cell_text_host, expand=False)
        host_name_column.set_cell_data_func(
                  cell_text_host, self._set_cell_text_host)
        host_name_column.set_sort_column_id(0)
        host_name_column.set_visible(False)

        # Construct the suite name column.
        suite_name_column = gtk.TreeViewColumn("Suite")
        cell_text_name = gtk.CellRendererText()
        suite_name_column.pack_start(cell_text_name, expand=False)
        suite_name_column.set_cell_data_func(
                   cell_text_name, self._set_cell_text_name)
        suite_name_column.set_sort_column_id(1)

        # Construct the suite title column.
        suite_title_column = gtk.TreeViewColumn("Title")
        cell_text_title = gtk.CellRendererText()
        suite_title_column.pack_start(cell_text_title, expand=False)
        suite_title_column.set_cell_data_func(
                   cell_text_title, self._set_cell_text_title)
        suite_title_column.set_sort_column_id(3)
        suite_title_column.set_visible(False)

        # Construct the update time column.
        time_column = gtk.TreeViewColumn("Updated")
        cell_text_time = gtk.CellRendererText()
        time_column.pack_start(cell_text_time, expand=False)
        time_column.set_cell_data_func(
                    cell_text_time, self._set_cell_text_time)
        time_column.set_sort_column_id(4)
        time_column.set_visible(False)

        # Construct the status column.
        status_column = gtk.TreeViewColumn("Status")
        status_column.set_sort_column_id(5)
        for i in range(5, 25):
            cell_pixbuf_state = gtk.CellRendererPixbuf()
            status_column.pack_start(cell_pixbuf_state, expand=False)
            status_column.set_cell_data_func(
                   cell_pixbuf_state, self._set_cell_pixbuf_state, i)

        self.suite_treeview.append_column(host_name_column)
        self.suite_treeview.append_column(suite_name_column)
        self.suite_treeview.append_column(suite_title_column)
        self.suite_treeview.append_column(time_column)
        self.suite_treeview.append_column(status_column)
        self.suite_treeview.show()
        if hasattr(self.suite_treeview, "set_has_tooltip"):
            self.suite_treeview.set_has_tooltip(True)
            try:
                self.suite_treeview.connect('query-tooltip',
                                            self._on_query_tooltip)
            except TypeError:
                # Lower PyGTK version.
                pass
        self.suite_treeview.connect("button-press-event",
                                    self._on_button_press_event)
        scrolled_window = gtk.ScrolledWindow()
        scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
                                   gtk.POLICY_AUTOMATIC)
        scrolled_window.add(self.suite_treeview)
        scrolled_window.show()
        self.vbox.pack_start(scrolled_window, expand=True, fill=True)
        self.updater = SummaryAppUpdater(self.hosts, suite_treemodel,
                                         owner=self.owner,
                                         poll_interval=poll_interval)
        self.updater.start()
        self.window.add(self.vbox)
        self.window.connect("destroy", self._on_destroy_event)
        self.window.set_default_size(200, 100)
        self.suite_treeview.grab_focus()
        self.window.show()

    def _on_button_press_event(self, treeview, event):
        # DISPLAY MENU ONLY ON RIGHT CLICK ONLY

        if (event.type != gtk.gdk._2BUTTON_PRESS and
            event.button != 3):
            return False

        treemodel = treeview.get_model()

        x = int(event.x)
        y = int(event.y)
        time = event.time
        pth = treeview.get_path_at_pos(x, y)

        suite_host_tuples = []

        if pth is not None:
            # Add a gcylc launcher item.
            path, col, cellx, celly = pth

            iter_ = treemodel.get_iter(path)
            host, suite = treemodel.get(iter_, 0, 1)
            suite_host_tuples.append((suite, host))

        if event.type == gtk.gdk._2BUTTON_PRESS:
            if suite_host_tuples:
                launch_gcylc(host, suite, owner=self.owner)
            return False

        has_stopped_suites = bool(self.updater.stop_summaries)

        view_item = gtk.ImageMenuItem("View Column...")
        img = gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_MENU)
        view_item.set_image(img)
        view_item.show()
        view_menu = gtk.Menu()
        view_item.set_submenu(view_menu)
        for column_index, column in enumerate(treeview.get_columns()):
            name = column.get_title()
            is_visible = column.get_visible()
            column_item = gtk.CheckMenuItem(name.replace("_", "__"))
            column_item._connect_args = (column_index, is_visible)
            column_item.set_active(is_visible)
            column_item.connect("toggled", self._on_toggle_column_visible)
            column_item.show()
            view_menu.append(column_item)

        menu = get_summary_menu(suite_host_tuples,
                                self.theme_name,
                                self._set_theme,
                                has_stopped_suites,
                                self.updater.clear_stopped_suites,
                                self.hosts,
                                self.updater.set_hosts,
                                self.updater.update_now,
                                self.updater.start,
                                program_name="cylc gsummary",
                                extra_items=[view_item],
                                owner=self.owner)
        menu.popup( None, None, None, event.button, event.time )
        return False

    def _on_destroy_event(self, widget):
        self.updater.quit = True
        gtk.main_quit()
        return False

    def _on_query_tooltip(self, widget, x, y, kbd_ctx, tooltip):
        """Handle a tooltip creation request."""
        tip_context = self.suite_treeview.get_tooltip_context(x, y, kbd_ctx)
        if tip_context is None:
            self._prev_tooltip_location_id = None
            return False
        x, y = self.suite_treeview.convert_widget_to_bin_window_coords(x, y)
        path, column, cell_x, cell_y = self.suite_treeview.get_path_at_pos(
                                                                    x, y)
        model = self.suite_treeview.get_model()
        iter_ = model.get_iter(path)
        host = model.get_value(iter_, 0)
        suite = model.get_value(iter_, 1)
        update_time = model.get_value(iter_, 4)

        location_id = (host, suite, update_time, column.get_title())
        if location_id != self._prev_tooltip_location_id:
            self._prev_tooltip_location_id = location_id
            tooltip.set_text(None)
            return False
        if column.get_title() in ["Host", "Suite"]:
            tooltip.set_text(suite + " - " + host)
            return True
        if column.get_title() == "Updated":
            time_point = get_timepoint_from_seconds_since_unix_epoch(
                update_time)
            tooltip.set_text("Info retrieved at " + str(time_point))
            return True
        if column.get_title() != "Status":
            tooltip.set_text(None)
            return False
        state_texts = []
        for i in range(5, 25):
            state_text = model.get_value(iter_, i)
            if state_text is None:
                break
            status, number = state_text.rsplit(" ", 1)
            state_texts.append(number + " " + status)
        text = "Tasks: " + ", ".join(state_texts)
        tooltip.set_text(text)
        return True

    def _on_toggle_column_visible(self, menu_item):
        column_index, is_visible = menu_item._connect_args
        column = self.suite_treeview.get_columns()[column_index]
        column.set_visible(not is_visible)
        return False

    def _set_cell_pixbuf_state(self, column, cell, model, iter_, index):
        state_info = model.get_value(iter_, index)
        if state_info is None:
            cell.set_property("pixbuf", None)
            cell.set_property("visible", False)
            return
        is_stopped = model.get_value(iter_, 2)
        state, num_tasks = state_info.rsplit(" ", 1)
        icon = self.dots.get_icon(state, is_stopped=is_stopped)
        cell.set_property("pixbuf", icon)
        cell.set_property("visible", True)

    def _set_cell_text_host(self, column, cell, model, iter_):
        host = model.get_value(iter_, 0)
        is_stopped = model.get_value(iter_, 2)
        cell.set_property("sensitive", not is_stopped)
        cell.set_property("text", host)

    def _set_cell_text_name(self, column, cell, model, iter_):
        name = model.get_value(iter_, 1)
        is_stopped = model.get_value(iter_, 2)
        cell.set_property("sensitive", not is_stopped)
        cell.set_property("text", name)

    def _set_cell_text_title(self, column, cell, model, iter_):
        title = model.get_value(iter_, 3)
        is_stopped = model.get_value(iter_, 2)
        cell.set_property("sensitive", not is_stopped)
        cell.set_property("text", title)

    def _set_cell_text_time(self, column, cell, model, iter_):
        update_time = model.get_value(iter_, 4)
        time_point = get_timepoint_from_seconds_since_unix_epoch(update_time)
        time_point.set_time_zone_to_local()
        time_string = str(time_point).split("T")[1]
        is_stopped = model.get_value(iter_, 2)
        cell.set_property("sensitive", not is_stopped)
        cell.set_property("text", time_string)

    def _set_theme(self, new_theme_name):
        self.theme_name = new_theme_name
        self.theme = gcfg.get( ['themes',self.theme_name] )
        self.dots = DotMaker(self.theme)

    def _set_tooltip(self, widget, text):
        tooltip = gtk.Tooltips()
        tooltip.enable()
        tooltip.set_tip(widget, text)
Beispiel #24
0
 def _set_theme(self, new_theme_name):
     self.theme_name = new_theme_name
     self.theme = self.usercfg['themes'][self.theme_name]
     self.dots = DotMaker(self.theme)
Beispiel #25
0
    def treeview_widgets(self):
        # Treeview of current suite state, with filtering and sorting.
        # sorting is handled somewhat manually because the simple method
        # of interposing a TreeModelSort at the top:
        #   treestore = gtk.TreeStore(str, ...)
        #   tms = gtk.TreeModelSort( treestore )   #\
        #   tmf = tms.filter_new()                 #-- or other way round?
        #   tv = gtk.TreeView()
        #   tv.set_model(tms)
        # failed to produce correct results (the data displayed was not
        # consistently what should have been displayed given the
        # filtering in use) although the exact same code worked for a
        # liststore.

        self.sort_col_num = 0

        self.ttreestore = gtk.TreeStore(str, str, str, str, str, str, str, str,
                                        str, str, gtk.gdk.Pixbuf)
        self.tmodelfilter = self.ttreestore.filter_new()
        self.tmodelfilter.set_visible_func(self.visible_cb)
        self.tmodelsort = gtk.TreeModelSort(self.tmodelfilter)
        self.ttreeview = gtk.TreeView()
        self.ttreeview.set_rules_hint(True)
        self.ttreeview.set_model(self.tmodelsort)

        ts = self.ttreeview.get_selection()
        ts.set_mode(gtk.SELECTION_SINGLE)

        self.ttreeview.connect('button_press_event',
                               self.on_treeview_button_pressed)
        headings = [
            None, 'task', 'state', 'host', 'Job ID', 'T-submit', 'T-start',
            'T-finish', 'dT-mean', 'latest message'
        ]

        for n in range(1, len(headings)):
            # Skip first column (cycle point)
            tvc = gtk.TreeViewColumn(headings[n])
            if n == 1:
                crp = gtk.CellRendererPixbuf()
                tvc.pack_start(crp, False)
                tvc.set_attributes(crp, pixbuf=10)
            cr = gtk.CellRendererText()
            tvc.pack_start(cr, True)
            if n == 7:
                tvc.set_attributes(cr, markup=n)
            else:
                tvc.set_attributes(cr, text=n)
            tvc.set_resizable(True)
            tvc.set_clickable(True)
            self.ttreeview.append_column(tvc)
            tvc.set_sort_column_id(n - 1)
            self.tmodelsort.set_sort_func(n - 1, self.sort_column, n - 1)
        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        sw.add(self.ttreeview)

        self.tfilterbox = gtk.VBox()
        subbox1 = gtk.HBox(homogeneous=True)
        subbox2 = gtk.HBox(homogeneous=True)
        self.tfilterbox.pack_start(subbox1)
        self.tfilterbox.pack_start(subbox2)

        self.tfilter_states = []

        dotm = DotMaker(self.theme, size='small')
        cnt = 0
        for st in task_state.legal:
            box = gtk.HBox()
            icon = dotm.get_image(st)
            cb = gtk.CheckButton(task_state.labels[st])
            tooltip = gtk.Tooltips()
            tooltip.enable()
            tooltip.set_tip(cb, "Filter by task state = %s" % st)

            box.pack_start(icon, expand=False)
            box.pack_start(cb, expand=False)
            cnt += 1
            if cnt > (len(task_state.legal) + 1) // 2:
                subbox2.pack_start(box, expand=False, fill=True)
            else:
                subbox1.pack_start(box, expand=False, fill=True)
            if st in self.tfilter_states:
                cb.set_active(False)
            else:
                cb.set_active(True)
            cb.connect('toggled', self.check_tfilter_buttons)

        self.filter_entry = EntryTempText()
        self.filter_entry.set_width_chars(7)
        self.filter_entry.connect("activate", self.check_filter_entry)
        self.filter_entry.set_temp_text("filter")
        tooltip = gtk.Tooltips()
        tooltip.enable()
        tooltip.set_tip(
            self.filter_entry, "Filter by task name.\n"
            "Enter a sub-string or regex and hit Enter\n"
            "(to reset, clear the entry and hit Enter)")
        subbox2.pack_start(self.filter_entry)
        cnt += 1

        if cnt % 2 != 0:
            # subbox2 needs another entry to line things up.
            subbox2.pack_start(gtk.HBox(), expand=False, fill=True)

        filter_hbox = gtk.HBox()
        filter_hbox.pack_start(self.tfilterbox, True, True, 10)
        vbox = gtk.VBox()
        vbox.pack_start(sw, True)
        vbox.pack_end(filter_hbox, False)

        return vbox
Beispiel #26
0
class SummaryPanelAppletUpdater(BaseSummaryTimeoutUpdater):

    """Update the summary panel applet - subclass of gsummary equivalent."""

    IDLE_STOPPED_TIME = 3600  # 1 hour.
    MAX_INDIVIDUAL_SUITES = 5

    def __init__(self, hosts, dot_hbox, gcylc_image, is_compact, owner=None,
                 poll_interval=None):
        self.quit = True
        self.dot_hbox = dot_hbox
        self.gcylc_image = gcylc_image
        self.is_compact = is_compact
        self._set_gcylc_image_tooltip()
        self.gcylc_image.set_sensitive(False)
        self.theme_name = gcfg.get( ['use theme'] )
        self.theme = gcfg.get( ['themes', self.theme_name] )
        self.dots = DotMaker(self.theme)
        self.statuses = {}
        self.stop_summaries = {}
        self._set_exception_hook()
        super(SummaryPanelAppletUpdater, self).__init__(
                              hosts, owner=owner, poll_interval=poll_interval)

    def clear_stopped_suites(self):
        """Clear stopped suite information that may have built up."""
        self.stop_summaries.clear()
        gobject.idle_add(self.update)

    def start(self):
        self.gcylc_image.set_sensitive(True)
        super(SummaryPanelAppletUpdater, self).start()
        self._set_gcylc_image_tooltip()

    def stop(self):
        self.gcylc_image.set_sensitive(False)
        super(SummaryPanelAppletUpdater, self).stop()
        self._set_gcylc_image_tooltip()

    def launch_context_menu(self, event, suite_host_tuples=None,
                            extra_items=None):
        has_stopped_suites = bool(self.stop_summaries)

        if suite_host_tuples is None:
            suite_host_tuples = []

        if extra_items is None:
            extra_items = []

        gsummary_item = gtk.ImageMenuItem("Launch cylc gsummary")
        img = gtk.image_new_from_stock("gcylc", gtk.ICON_SIZE_MENU)
        gsummary_item.set_image(img)
        gsummary_item.show()
        gsummary_item.connect("button-press-event",
                                self._on_button_press_event_gsummary)

        extra_items.append(gsummary_item)

        menu = get_summary_menu(suite_host_tuples, 
                                self.theme_name, self._set_theme,
                                has_stopped_suites,
                                self.clear_stopped_suites,
                                self.hosts,
                                self.set_hosts,
                                self.update_now,
                                self.start,
                                program_name="cylc gpanel",
                                extra_items=extra_items,
                                owner=self.owner,
                                is_stopped=self.quit)
        menu.popup( None, None, None, event.button, event.time )
        return False

    def update(self, update_time=None):
        """Update the Applet."""
        suite_host_tuples = []
        statuses = copy.deepcopy(self.statuses)
        stop_summaries = copy.deepcopy(self.stop_summaries)
        for host in self.hosts:
            suites = (statuses.get(host, {}).keys() +
                      stop_summaries.get(host, {}).keys())
            for suite in suites:
                suite_host_tuples.append((suite, host))
        suite_host_tuples.sort()
        for child in self.dot_hbox.get_children():
            self.dot_hbox.remove(child)
        number_mode = (not self.is_compact and
                       len(suite_host_tuples) > self.MAX_INDIVIDUAL_SUITES)
        suite_statuses = {}
        compact_suite_statuses = []
        for suite, host in suite_host_tuples:
            if suite in statuses.get(host, {}):
                status_map = statuses[host][suite]
                is_stopped = False
            else:
                info = stop_summaries[host][suite]
                status_map, suite_time = info
                is_stopped = True
            status = extract_group_state(status_map.keys(),
                                         is_stopped=is_stopped)
            if number_mode:
                suite_statuses.setdefault(is_stopped, {})
                suite_statuses[is_stopped].setdefault(status, [])
                suite_statuses[is_stopped][status].append(
                                           (suite, host, status_map.items()))
            elif self.is_compact:
                compact_suite_statuses.append((suite, host, status,
                                               status_map.items(), is_stopped))
            else:
                self._add_image_box([(suite, host, status, status_map.items(),
                                      is_stopped)])
        if number_mode:
            for is_stopped in sorted(suite_statuses.keys()):
                statuses = suite_statuses[is_stopped].items()
                statuses.sort(lambda x, y: cmp(len(y[1]), len(x[1])))
                for status, suite_host_states_tuples in statuses:
                    label = gtk.Label(
                                str(len(suite_host_states_tuples)) + ":")
                    label.show()
                    self.dot_hbox.pack_start(label, expand=False, fill=False)
                    suite_info_tuples = []
                    for suite, host, task_states in suite_host_states_tuples:
                        suite_info_tuples.append((suite, host, status,
                                                  task_states, is_stopped))
                    self._add_image_box(suite_info_tuples)
        if self.is_compact:
            if not compact_suite_statuses:
                # No suites running or stopped.
                self.gcylc_image.show()
                return False
            self.gcylc_image.hide()
            self._add_image_box(compact_suite_statuses)
        return False

    def _add_image_box(self, suite_host_info_tuples):
        image_eb = gtk.EventBox()
        image_eb.show()
        is_all_stopped = False
        running_status_list = []
        status_list = []
        suite_host_tuples = []
        for info_tuple in suite_host_info_tuples:
            suite, host, status, task_states, is_stopped = info_tuple
            suite_host_tuples.append((suite, host))
            if not is_stopped:
                running_status_list.append(status)
            status_list.append(status)
        if running_status_list:
            status = extract_group_state(running_status_list,
                                         is_stopped=False)
            image = self.dots.get_image(status, is_stopped=False)
        else:
            status = extract_group_state(status_list, is_stopped=True)
            image = self.dots.get_image(status, is_stopped=True)
        image.show()
        image_eb.add(image)
        image_eb._connect_args = suite_host_tuples
        image_eb.connect("button-press-event",
                         self._on_button_press_event)

        text_format = "%s - %s - %s"
        long_text_format = text_format + "\n    Tasks: %s\n"
        text = ""
        tip_vbox = gtk.VBox()  # Only used in PyGTK 2.12+
        tip_vbox.show()
        for info_tuple in suite_host_info_tuples:
            suite, host, status, task_states, is_stopped = info_tuple
            task_states.sort(lambda x, y: cmp(len(y[1]), len(x[1])))
            tip_hbox = gtk.HBox()
            tip_hbox.show()
            state_info = []
            for state_name, tasks in task_states:
                state_info.append(str(len(tasks)) + " " + state_name)
                image = self.dots.get_image(state_name, is_stopped=is_stopped)
                image.show()
                tip_hbox.pack_start(image, expand=False, fill=False)
            states_text = ", ".join(state_info)
            if status is None:
                suite_summary = "?"
            else:
                suite_summary = status
            if is_stopped:
                suite_summary = "stopped with " + suite_summary
            tip_label = gtk.Label(text_format % (suite, suite_summary, host))
            tip_label.show()
            tip_hbox.pack_start(tip_label, expand=False, fill=False,
                                padding=5)
            tip_vbox.pack_start(tip_hbox, expand=False, fill=False)
            text += long_text_format % (suite, suite_summary, host, states_text)
        text = text.rstrip()
        if hasattr(gtk, "Tooltip"):
            image_eb.set_has_tooltip(True)
            image_eb.connect("query-tooltip", self._on_img_tooltip_query,
                             tip_vbox)
        else:
            self._set_tooltip(image_eb, text)
        self.dot_hbox.pack_start(image_eb, expand=False, fill=False,
                                 padding=1)

    def _on_button_press_event(self, widget, event):
        if event.button == 1:
            self.launch_context_menu(event,
                                     suite_host_tuples=widget._connect_args)
        return False

    def _on_button_press_event_gsummary(self, widget, event):
        launch_gsummary(hosts=self.hosts, owner=self.owner)

    def _on_img_tooltip_query(self, widget, x, y, kbd, tooltip, tip_widget):
        tooltip.set_custom(tip_widget)
        return True

    def _set_exception_hook(self):
        # Handle an uncaught exception.
        old_hook = sys.excepthook
        sys.excepthook = (lambda *a:
                          self._handle_exception(*a, old_hook=old_hook))

    def _handle_exception(self, e_type, e_value, e_traceback,
                          old_hook=None):
        self.gcylc_image.set_from_stock(gtk.STOCK_DIALOG_ERROR,
                                        gtk.ICON_SIZE_MENU)
        exc_lines = traceback.format_exception(e_type, e_value, e_traceback)
        exc_text = "".join(exc_lines)
        info = "cylc gpanel has a problem.\n\n%s" % exc_text
        self._set_tooltip(self.gcylc_image, info.rstrip())
        if old_hook is not None:
            old_hook(exception_class, exception, trace)

    def _set_gcylc_image_tooltip(self):
        if self.quit:
            self._set_tooltip(self.gcylc_image, "Cylc Applet - Off")
        else:
            self._set_tooltip(self.gcylc_image, "Cylc Applet - Active")

    def _set_theme(self, new_theme_name):
        self.theme_name = new_theme_name
        self.theme = gcfg.get( ['themes', self.theme_name] )
        self.dots = DotMaker(self.theme)

    def _set_tooltip(self, widget, text):
        tooltip = gtk.Tooltips()
        tooltip.enable()
        tooltip.set_tip(widget, text)