Ejemplo n.º 1
0
class AnalyzeJournal(activity.Activity):
    def __init__(self, handle):

        activity.Activity.__init__(self, handle, True)

        self.max_participants = 1

        # CHART_OPTIONS

        self.x_label = ""
        self.y_label = ""
        self.chart_color = utils.get_user_fill_color('str')
        self.chart_line_color = utils.get_user_stroke_color('str')
        self.current_chart = None
        self.charts_area = None
        self.chart_data = []

        # TOOLBARS
        toolbarbox = ToolbarBox()

        activity_button = ActivityToolbarButton(self)
        activity_btn_toolbar = activity_button.page

        activity_btn_toolbar.title.connect('changed', self._set_chart_title)

        save_as_image = ToolButton("save-as-image")
        save_as_image.connect("clicked", self._save_as_image)
        save_as_image.set_tooltip(_("Save as image"))
        activity_btn_toolbar.insert(save_as_image, -1)

        save_as_image.show()

        toolbarbox.toolbar.insert(activity_button, 0)

        import_freespace = ToolButton("import-freespace")
        import_freespace.connect("clicked", self.__import_freespace_cb)
        import_freespace.set_tooltip(_("Read Freespace data"))
        toolbarbox.toolbar.insert(import_freespace, -1)
        import_freespace.show()

        import_journal = ToolButton('import-journal')
        import_journal.connect('clicked', self.__import_journal_cb)
        import_journal.set_tooltip(_('Read Journal data'))
        toolbarbox.toolbar.insert(import_journal, -1)
        import_journal.show()

        import_turtle = ToolButton('import-turtle')
        import_turtle.connect('clicked', self.__import_turtle_cb)
        import_turtle.set_tooltip(_('Read Turtle data'))
        toolbarbox.toolbar.insert(import_turtle, -1)
        import_turtle.show()

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        add_vbar_chart = RadioToolButton()
        add_vbar_chart.connect("clicked", self._add_chart_cb, "vbar")
        add_vbar_chart.set_tooltip(_("Vertical Bar Chart"))
        add_vbar_chart.props.icon_name = "vbar"
        charts_group = add_vbar_chart
        toolbarbox.toolbar.insert(add_vbar_chart, -1)

        add_hbar_chart = RadioToolButton()
        add_hbar_chart.connect("clicked", self._add_chart_cb, "hbar")
        add_hbar_chart.set_tooltip(_("Horizontal Bar Chart"))
        add_hbar_chart.props.icon_name = "hbar"
        add_hbar_chart.props.group = charts_group
        toolbarbox.toolbar.insert(add_hbar_chart, -1)

        add_pie_chart = RadioToolButton()
        add_pie_chart.connect("clicked", self._add_chart_cb, "pie")
        add_pie_chart.set_tooltip(_("Pie Chart"))
        add_pie_chart.props.icon_name = "pie"
        add_pie_chart.props.group = charts_group
        add_pie_chart.set_active(True)
        toolbarbox.toolbar.insert(add_pie_chart, -1)

        self.chart_type_buttons = [
            add_vbar_chart, add_hbar_chart, add_pie_chart
        ]

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        fullscreen_btn = ToolButton('view-fullscreen')
        fullscreen_btn.set_tooltip(_('Fullscreen'))
        fullscreen_btn.connect("clicked", self.__fullscreen_cb)

        toolbarbox.toolbar.insert(fullscreen_btn, -1)

        charthelp.create_help(toolbarbox.toolbar)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(True)
        toolbarbox.toolbar.insert(separator, -1)

        stopbtn = StopButton(self)
        toolbarbox.toolbar.insert(stopbtn, -1)

        self.set_toolbar_box(toolbarbox)

        # CANVAS
        paned = gtk.HPaned()
        box = gtk.VBox()
        self.box = box

        # Set the info box width to 1/3 of the screen:
        def size_allocate_cb(widget, allocation):
            paned.disconnect(self._setup_handle)
            box_width = allocation.width / 3
            box.set_size_request(box_width, -1)

        self._setup_handle = paned.connect('size_allocate', size_allocate_cb)

        scroll = gtk.ScrolledWindow()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.labels_and_values = ChartData(self)
        scroll.add(self.labels_and_values)

        self.labels_and_values.connect("label-changed", self._label_changed)
        self.labels_and_values.connect("value-changed", self._value_changed)

        box.pack_start(scroll, True, True, 0)

        paned.add1(box)

        # CHARTS AREA

        eventbox = gtk.EventBox()
        self.charts_area = ChartArea(self)
        self.charts_area.connect('size_allocate', self._chart_size_allocate)

        eventbox.modify_bg(gtk.STATE_NORMAL, _WHITE)

        eventbox.add(self.charts_area)
        paned.add2(eventbox)

        self.set_canvas(paned)

        self.show_all()

    def _add_chart_cb(self, widget, type="vbar"):
        self.current_chart = Chart(type)

        self.update_chart()

    def _chart_size_allocate(self, widget, allocation):
        self._render_chart()

    def unfullscreen(self):
        self.box.show()
        activity.Activity.unfullscreen(self)

    def __fullscreen_cb(self, button):
        self.box.hide()
        self._render_chart(fullscreen=True)
        activity.Activity.fullscreen(self)

    def _render_chart(self, fullscreen=False):
        if self.current_chart is None or self.charts_area is None:
            return

        try:
            # Resize the chart for all the screen sizes
            xpos, ypos, width, height = self.get_allocation()

            if fullscreen:
                new_width = width
                new_height = height

            if not fullscreen:
                sxpos, sypos, width, height = self.charts_area.get_allocation()

                new_width = width - 40
                new_height = height - 40

            self.current_chart.width = new_width
            self.current_chart.height = new_height

            # Set options
            self.current_chart.set_color_scheme(color=self.chart_color)
            self.current_chart.set_line_color(self.chart_line_color)

            if self.current_chart.type == "pie":
                self.current_chart.render(self)
            else:
                self.current_chart.render()
            self.charts_area.queue_draw()

        except (ZeroDivisionError, ValueError):
            pass

        return False

    def _update_chart_data(self):
        if self.current_chart is None:
            return
        self.current_chart.data_set(self.chart_data)
        self._update_chart_labels()

    def _set_chart_title(self, widget):
        self._update_chart_labels(title=widget.get_text())

    def _update_chart_labels(self, title=""):
        if self.current_chart is None:
            return

        if not title and self.metadata["title"]:
            title = self.metadata["title"]

        self.current_chart.set_title(title)
        self.current_chart.set_x_label(self.x_label)
        self.current_chart.set_y_label(self.y_label)
        self._render_chart()

    def update_chart(self):
        if self.current_chart:
            self.current_chart.data_set(self.chart_data)
            self.current_chart.set_title(self.metadata["title"])
            self.current_chart.set_x_label(self.x_label)
            self.current_chart.set_y_label(self.y_label)
            self._render_chart()

    def _label_changed(self, treeview, path, new_label):
        path = int(path)
        self.chart_data[path] = (new_label, self.chart_data[path][1])
        self._update_chart_data()

    def _value_changed(self, treeview, path, new_value):
        path = int(path)
        self.chart_data[path] = (self.chart_data[path][0], float(new_value))
        self._update_chart_data()

    def _set_h_label(self, widget):
        new_text = widget.get_text()

        if new_text != self.h_label._text:
            self.x_label = new_text
            self._update_chart_labels()

    def _set_v_label(self, widget):
        new_text = widget.get_text()

        if new_text != self.v_label._text:
            self.y_label = new_text
            self._update_chart_labels()

    def _set_chart_color(self, widget, pspec):
        self.chart_color = utils.rgb2html(widget.get_color())
        self._render_chart()

    def _set_chart_line_color(self, widget, pspec):
        self.chart_line_color = utils.rgb2html(widget.get_color())
        self._render_chart()

    def _object_chooser(self, mime_type, type_name):
        chooser = ObjectChooser()
        matches_mime_type = False

        response = chooser.run()
        if response == gtk.RESPONSE_ACCEPT:
            jobject = chooser.get_selected_object()
            metadata = jobject.metadata
            file_path = jobject.file_path

            if metadata['mime_type'] == mime_type:
                matches_mime_type = True

            else:
                alert = Alert()

                alert.props.title = _('Invalid object')
                alert.props.msg = \
                       _('The selected object must be a %s file' % (type_name))

                ok_icon = Icon(icon_name='dialog-ok')
                alert.add_button(gtk.RESPONSE_OK, _('Ok'), ok_icon)
                ok_icon.show()

                alert.connect('response', lambda a, r: self.remove_alert(a))

                self.add_alert(alert)

                alert.show()

        return matches_mime_type, file_path, metadata['title']

    def _graph_from_reader(self, reader):
        self.labels_and_values.model.clear()
        self.chart_data = []

        chart_data = reader.get_chart_data()
        horizontal, vertical = reader.get_labels_name()

        # Load the data
        for row in chart_data:
            self._add_value(None, label=row[0], value=float(row[1]))

            self.update_chart()

    def _add_value(self, widget, label="", value="0.0"):
        data = (label, float(value))
        if not data in self.chart_data:
            pos = self.labels_and_values.add_value(label, value)
            self.chart_data.insert(pos, data)
            self._update_chart_data()

    def _remove_value(self, widget):
        path = self.labels_and_values.remove_selected_value()
        del self.chart_data[path]
        self._update_chart_data()

    def __import_freespace_cb(self, widget):
        reader = FreeSpaceReader()
        self._graph_from_reader(reader)

    def __import_journal_cb(self, widget):
        reader = JournalReader()
        self._graph_from_reader(reader)

    def __import_turtle_cb(self, widget):
        matches_mime_type, file_path, title = self._object_chooser(
            'application/x-turtle-art', _('Turtle'))
        if matches_mime_type:
            reader = TurtleReader(file_path)
            self._graph_from_reader(reader)

    def _save_as_image(self, widget):
        if self.current_chart:
            jobject = datastore.create()

            jobject.metadata['title'] = self.metadata["title"]
            jobject.metadata['mime_type'] = "image/png"

            self.current_chart.as_png(_CHART_FILE)
            jobject.set_file_path(_CHART_FILE)

            datastore.write(jobject)

    def load_from_file(self, f):
        try:
            data = simplejson.load(f)
        finally:
            f.close()

        self.metadata["title"] = data['title']
        self.x_label = data['x_label']
        self.y_label = data['y_label']
        self.chart_color = data['chart_color']
        self.chart_line_color = data['chart_line_color']
        self.current_chart.type = data['current_chart.type']
        chart_data = data['chart_data']

        # Update charts buttons
        _type = data["current_chart.type"]
        if _type == "vbar":
            self.chart_type_buttons[0].set_active(True)

        elif _type == "hbar":
            self.chart_type_buttons[1].set_active(True)

        elif _type == "line":
            self.chart_type_buttons[2].set_active(True)

        elif _type == "pie":
            self.chart_type_buttons[3].set_active(True)

        #load the data
        for row in chart_data:
            self._add_value(None, label=row[0], value=float(row[1]))

        self.update_chart()

    def write_file(self, file_path):
        self.metadata['mime_type'] = "application/x-chart-activity"
        if self.current_chart:

            data = {}
            data['title'] = self.metadata["title"]
            data['x_label'] = self.x_label
            data['y_label'] = self.y_label
            data['chart_color'] = self.chart_color
            data['chart_line_color'] = self.chart_line_color
            data['current_chart.type'] = self.current_chart.type
            data['chart_data'] = self.chart_data

            f = open(file_path, 'w')
            try:
                simplejson.dump(data, f)
            finally:
                f.close()

    def read_file(self, file_path):
        f = open(file_path, 'r')
        self.load_from_file(f)
Ejemplo n.º 2
0
class SimpleGraph(activity.Activity):
    def __init__(self, handle):

        activity.Activity.__init__(self, handle, True)

        self.max_participants = 1

        # CHART_OPTIONS

        self.x_label = ""
        self.y_label = ""
        self.chart_color = utils.get_user_fill_color('str')
        self.chart_line_color = utils.get_user_stroke_color('str')
        self.current_chart = None
        self.charts_area = None
        self.chart_data = []

        # TOOLBARS
        toolbarbox = ToolbarBox()

        activity_button = ActivityToolbarButton(self)
        activity_btn_toolbar = activity_button.page

        activity_btn_toolbar.title.connect('changed', self._set_chart_title)

        save_as_image = ToolButton("save-as-image")
        save_as_image.connect("clicked", self._save_as_image)
        save_as_image.set_tooltip(_("Save as image"))
        activity_btn_toolbar.insert(save_as_image, -1)

        save_as_image.show()

        import_stopwatch = ToolButton("import-stopwatch")
        import_stopwatch.connect("clicked", self.__import_stopwatch_cb)
        import_stopwatch.set_tooltip(_("Read StopWatch data"))
        activity_btn_toolbar.insert(import_stopwatch, -1)

        import_stopwatch.show()

        import_measure = ToolButton("import-measure")
        import_measure.set_tooltip(_("Read Measure data"))

        if utils.get_channels() == 1:
            import_measure.connect("clicked", self.__import_measure_cb, 1)

        else:
            import_measure.connect("clicked", self._measure_btn_clicked)
            self._create_measure_palette(import_measure)

        activity_btn_toolbar.insert(import_measure, -1)

        import_measure.show()

        activity_btn_toolbar.keep.hide()

        toolbarbox.toolbar.insert(activity_button, 0)

        add_v = ToolButton("row-insert")
        add_v.connect("clicked", self._add_value)
        add_v.set_tooltip(_("Add a value"))

        toolbarbox.toolbar.insert(add_v, -1)

        remove_v = ToolButton("row-remove")
        remove_v.connect("clicked", self._remove_value)
        remove_v.set_tooltip(_("Remove the selected value"))

        toolbarbox.toolbar.insert(remove_v, -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        add_vbar_chart = RadioToolButton()
        add_vbar_chart.connect("clicked", self._add_chart_cb, "vbar")
        add_vbar_chart.set_tooltip(_("Vertical Bar Chart"))
        add_vbar_chart.props.icon_name = "vbar"
        charts_group = add_vbar_chart

        toolbarbox.toolbar.insert(add_vbar_chart, -1)

        add_hbar_chart = RadioToolButton()
        add_hbar_chart.connect("clicked", self._add_chart_cb, "hbar")
        add_hbar_chart.set_tooltip(_("Horizontal Bar Chart"))
        add_hbar_chart.props.icon_name = "hbar"
        add_hbar_chart.props.group = charts_group
        toolbarbox.toolbar.insert(add_hbar_chart, -1)

        add_line_chart = RadioToolButton()
        add_line_chart.connect("clicked", self._add_chart_cb, "line")
        add_line_chart.set_tooltip(_("Line Chart"))
        add_line_chart.props.icon_name = "line"
        add_line_chart.props.group = charts_group
        toolbarbox.toolbar.insert(add_line_chart, -1)

        add_pie_chart = RadioToolButton()
        add_pie_chart.connect("clicked", self._add_chart_cb, "pie")
        add_pie_chart.set_tooltip(_("Pie Chart"))
        add_pie_chart.props.icon_name = "pie"
        add_pie_chart.props.group = charts_group
        add_pie_chart.set_active(True)
        toolbarbox.toolbar.insert(add_pie_chart, -1)

        self.chart_type_buttons = [
            add_vbar_chart, add_hbar_chart, add_line_chart, add_pie_chart
        ]

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        options_button = ToolbarButton(icon_name='preferences-system')
        options_toolbar = gtk.Toolbar()

        self.chart_color_btn = ColorToolButton()
        self.chart_color_btn.set_color(_COLOR1)
        self.chart_color_btn.set_title(_("Chart Color"))
        self.chart_color_btn.connect('notify::color', self._set_chart_color)
        options_toolbar.insert(self.chart_color_btn, -1)

        self.line_color_btn = ColorToolButton()
        self.line_color_btn.set_color(_COLOR2)
        self.line_color_btn.set_title(_("Line Color"))
        self.line_color_btn.connect('notify::color',
                                    self._set_chart_line_color)
        options_toolbar.insert(self.line_color_btn, -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        options_toolbar.insert(separator, -1)

        h_label_icon = Icon(icon_name="hlabel")
        h_label_tool_item = gtk.ToolItem()
        h_label_tool_item.add(h_label_icon)
        options_toolbar.insert(h_label_tool_item, -1)

        self.h_label = Entry(_("Horizontal label..."))
        self.h_label.entry.connect("changed", self._set_h_label)
        options_toolbar.insert(self.h_label, -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(False)
        options_toolbar.insert(separator, -1)

        v_label_icon = Icon(icon_name="vlabel")
        v_label_tool_item = gtk.ToolItem()
        v_label_tool_item.add(v_label_icon)
        options_toolbar.insert(v_label_tool_item, -1)

        self.v_label = Entry(_("Vertical label..."))
        self.v_label.entry.connect("changed", self._set_v_label)
        options_toolbar.insert(self.v_label, -1)

        options_button.props.page = options_toolbar
        options_toolbar.show_all()

        toolbarbox.toolbar.insert(options_button, -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        fullscreen_btn = ToolButton('view-fullscreen')
        fullscreen_btn.set_tooltip(_('Fullscreen'))
        fullscreen_btn.connect("clicked", self.__fullscreen_cb)

        toolbarbox.toolbar.insert(fullscreen_btn, -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(True)
        toolbarbox.toolbar.insert(separator, -1)

        simplegraphhelp.create_help(toolbarbox.toolbar)

        stopbtn = StopButton(self)
        toolbarbox.toolbar.insert(stopbtn, -1)

        self.set_toolbar_box(toolbarbox)

        # CANVAS
        paned = gtk.HPaned()
        box = gtk.VBox()
        self.box = box

        # Set the info box width to 1/3 of the screen:
        def size_allocate_cb(widget, allocation):
            paned.disconnect(self._setup_handle)
            box_width = allocation.width / 3
            box.set_size_request(box_width, -1)

        self._setup_handle = paned.connect('size_allocate', size_allocate_cb)

        scroll = gtk.ScrolledWindow()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.labels_and_values = ChartData(self)
        scroll.add(self.labels_and_values)

        self.labels_and_values.connect("label-changed", self._label_changed)
        self.labels_and_values.connect("value-changed", self._value_changed)

        box.pack_start(scroll, True, True, 0)

        paned.add1(box)

        # CHARTS AREA

        eventbox = gtk.EventBox()
        self.charts_area = ChartArea(self)
        self.charts_area.connect('size_allocate', self._chart_size_allocate)

        eventbox.modify_bg(gtk.STATE_NORMAL, _WHITE)

        eventbox.add(self.charts_area)
        paned.add2(eventbox)

        self.set_canvas(paned)

        self.show_all()

    def _create_measure_palette(self, button):
        palette = button.get_palette()
        hbox = gtk.HBox()

        channel1 = ToolButton("measure-channel-1")
        channel1.connect("clicked", self.__import_measure_cb, 1)

        channel2 = ToolButton("measure-channel-2")
        channel2.connect("clicked", self.__import_measure_cb, 2)

        hbox.pack_start(channel1, False, True, 0)
        hbox.pack_end(channel2, False, True, 0)

        hbox.show_all()

        palette.set_content(hbox)

    def _measure_btn_clicked(self, button):
        palette = button.get_palette()
        palette.popup()

    def _add_value(self, widget, label="", value="0.0"):
        data = (label, float(value))
        if not data in self.chart_data:
            pos = self.labels_and_values.add_value(label, value)
            self.chart_data.insert(pos, data)
            self._update_chart_data()

    def _remove_value(self, widget):
        path = self.labels_and_values.remove_selected_value()
        del self.chart_data[path]
        self._update_chart_data()

    def _add_chart_cb(self, widget, type="vbar"):
        self.current_chart = Chart(type)

        self.update_chart()

    def _chart_size_allocate(self, widget, allocation):
        self._render_chart()

    def unfullscreen(self):
        self.box.show()
        activity.Activity.unfullscreen(self)

    def __fullscreen_cb(self, button):
        self.box.hide()
        self._render_chart(fullscreen=True)
        activity.Activity.fullscreen(self)

    def _render_chart(self, fullscreen=False):
        if self.current_chart is None or self.charts_area is None:
            return

        try:
            # Resize the chart for all the screen sizes
            xpos, ypos, width, height = self.get_allocation()

            if fullscreen:
                new_width = width
                new_height = height

            if not fullscreen:
                sxpos, sypos, width, height = self.charts_area.get_allocation()

                new_width = width - 40
                new_height = height - 40

            self.current_chart.width = new_width
            self.current_chart.height = new_height

            # Set options
            self.current_chart.set_color_scheme(color=self.chart_color)
            self.current_chart.set_line_color(self.chart_line_color)

            if self.current_chart.type == "pie":
                self.current_chart.render(self)
            else:
                self.current_chart.render()
            self.charts_area.queue_draw()

        except (ZeroDivisionError, ValueError):
            pass

        return False

    def _update_chart_data(self):
        if self.current_chart is None:
            return
        self.current_chart.data_set(self.chart_data)
        self._update_chart_labels()

    def _set_chart_title(self, widget):
        self._update_chart_labels(title=widget.get_text())

    def _update_chart_labels(self, title=""):
        if self.current_chart is None:
            return

        if not title and self.metadata["title"]:
            title = self.metadata["title"]

        self.current_chart.set_title(title)
        self.current_chart.set_x_label(self.x_label)
        self.current_chart.set_y_label(self.y_label)
        self._render_chart()

    def update_chart(self):
        if self.current_chart:
            self.current_chart.data_set(self.chart_data)
            self.current_chart.set_title(self.metadata["title"])
            self.current_chart.set_x_label(self.x_label)
            self.current_chart.set_y_label(self.y_label)
            self._render_chart()

    def _label_changed(self, treeview, path, new_label):
        path = int(path)
        self.chart_data[path] = (new_label, self.chart_data[path][1])
        self._update_chart_data()

    def _value_changed(self, treeview, path, new_value):
        path = int(path)
        self.chart_data[path] = (self.chart_data[path][0], float(new_value))
        self._update_chart_data()

    def _set_h_label(self, widget):
        new_text = widget.get_text()

        if new_text != self.h_label._text:
            self.x_label = new_text
            self._update_chart_labels()

    def _set_v_label(self, widget):
        new_text = widget.get_text()

        if new_text != self.v_label._text:
            self.y_label = new_text
            self._update_chart_labels()

    def _set_chart_color(self, widget, pspec):
        self.chart_color = utils.rgb2html(widget.get_color())
        self._render_chart()

    def _set_chart_line_color(self, widget, pspec):
        self.chart_line_color = utils.rgb2html(widget.get_color())
        self._render_chart()

    def _object_chooser(self, mime_type, type_name):
        chooser = ObjectChooser()
        matches_mime_type = False

        response = chooser.run()
        if response == gtk.RESPONSE_ACCEPT:
            jobject = chooser.get_selected_object()
            metadata = jobject.metadata
            file_path = jobject.file_path

            if metadata['mime_type'] == mime_type:
                matches_mime_type = True

            else:
                alert = Alert()

                alert.props.title = _('Invalid object')
                alert.props.msg = \
                       _('The selected object must be a %s file' % (type_name))

                ok_icon = Icon(icon_name='dialog-ok')
                alert.add_button(gtk.RESPONSE_OK, _('Ok'), ok_icon)
                ok_icon.show()

                alert.connect('response', lambda a, r: self.remove_alert(a))

                self.add_alert(alert)

                alert.show()

        return matches_mime_type, file_path, metadata['title']

    def _graph_from_reader(self, reader):
        self.labels_and_values.model.clear()
        self.chart_data = []

        chart_data = reader.get_chart_data()

        horizontal, vertical = reader.get_labels_name()

        self.v_label.entry.set_text(horizontal)
        self.h_label.entry.set_text(vertical)

        # Load the data
        for row in chart_data:
            self._add_value(None, label=row[0], value=float(row[1]))

            self.update_chart()

    def __import_stopwatch_cb(self, widget):
        matches_mime_type, file_path, title = self._object_chooser(
            _STOPWATCH_MIME_TYPE, _('StopWatch'))

        if matches_mime_type:
            f = open(file_path)
            reader = StopWatchReader(f)
            self._graph_from_reader(reader)

            f.close()

    def __import_measure_cb(self, widget, channel=1):
        matches_mime_type, file_path, title = self._object_chooser(
            _CSV_MIME_TYPE, _('Measure'))

        if matches_mime_type:
            f = open(file_path)
            reader = MeasureReader(f, channel)
            self._graph_from_reader(reader)

            f.close()

    def _save_as_image(self, widget):
        if self.current_chart:
            jobject = datastore.create()

            jobject.metadata['title'] = self.metadata["title"]
            jobject.metadata['mime_type'] = "image/png"

            self.current_chart.as_png(_CHART_FILE)
            jobject.set_file_path(_CHART_FILE)

            datastore.write(jobject)

    def write_file(self, file_path):
        self.metadata['mime_type'] = "application/x-simplegraph-activity"
        if self.current_chart:

            data = {}
            data['title'] = self.metadata["title"]
            data['x_label'] = self.x_label
            data['y_label'] = self.y_label
            data['chart_color'] = self.chart_color
            data['chart_line_color'] = self.chart_line_color
            data['current_chart.type'] = self.current_chart.type
            data['chart_data'] = self.chart_data

            f = open(file_path, 'w')
            try:
                simplejson.dump(data, f)
            finally:
                f.close()

    def read_file(self, file_path):
        f = open(file_path, 'r')
        try:
            data = simplejson.load(f)
        finally:
            f.close()

        self.metadata["title"] = data['title']
        self.x_label = data['x_label']
        self.y_label = data['y_label']
        self.chart_color = data['chart_color']
        self.chart_line_color = data['chart_line_color']
        self.current_chart.type = data['current_chart.type']
        chart_data = data['chart_data']

        # Update charts buttons
        type = data["current_chart.type"]
        if type == "vbar":
            self.chart_type_buttons[0].set_active(True)

        elif type == "hbar":
            self.chart_type_buttons[1].set_active(True)

        elif type == "line":
            self.chart_type_buttons[2].set_active(True)

        elif type == "pie":
            self.chart_type_buttons[3].set_active(True)

        # Update the controls in the config subtoolbar
        self.chart_color_btn.set_color(gtk.gdk.Color(self.chart_color))
        self.line_color_btn.set_color(gtk.gdk.Color(self.chart_line_color))

        # If the saved label is not '', set the text entry with the saved label
        if self.x_label != '':
            self.h_label.entry.set_text(self.x_label)

        if self.y_label != '':
            self.v_label.entry.set_text(self.y_label)

        #load the data
        for row in chart_data:
            self._add_value(None, label=row[0], value=float(row[1]))

        self.update_chart()
Ejemplo n.º 3
0
class AnalyzeJournal(activity.Activity):

    def __init__(self, handle):

        activity.Activity.__init__(self, handle, True)

        self.max_participants = 1

        # CHART_OPTIONS

        self.x_label = ""
        self.y_label = ""
        self.chart_color = utils.get_user_fill_color('str')
        self.chart_line_color = utils.get_user_stroke_color('str')
        self.current_chart = None
        self.charts_area = None
        self.chart_data = []

        # TOOLBARS
        toolbarbox = ToolbarBox()

        activity_button = ActivityToolbarButton(self)
        activity_btn_toolbar = activity_button.page

        activity_btn_toolbar.title.connect('changed', self._set_chart_title)

        save_as_image = ToolButton("save-as-image")
        save_as_image.connect("clicked", self._save_as_image)
        save_as_image.set_tooltip(_("Save as image"))
        activity_btn_toolbar.insert(save_as_image, -1)

        save_as_image.show()

        toolbarbox.toolbar.insert(activity_button, 0)

        import_freespace = ToolButton("import-freespace")
        import_freespace.connect("clicked", self.__import_freespace_cb)
        import_freespace.set_tooltip(_("Read Freespace data"))
        toolbarbox.toolbar.insert(import_freespace, -1)
        import_freespace.show()

        import_journal = ToolButton('import-journal')
        import_journal.connect('clicked', self.__import_journal_cb)
        import_journal.set_tooltip(_('Read Journal data'))
        toolbarbox.toolbar.insert(import_journal, -1)
        import_journal.show()

        import_turtle = ToolButton('import-turtle')
        import_turtle.connect('clicked', self.__import_turtle_cb)
        import_turtle.set_tooltip(_('Read Turtle data'))
        toolbarbox.toolbar.insert(import_turtle, -1)
        import_turtle.show()

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        add_vbar_chart = RadioToolButton()
        add_vbar_chart.connect("clicked", self._add_chart_cb, "vbar")
        add_vbar_chart.set_tooltip(_("Vertical Bar Chart"))
        add_vbar_chart.props.icon_name = "vbar"
        charts_group = add_vbar_chart
        toolbarbox.toolbar.insert(add_vbar_chart, -1)

        add_hbar_chart = RadioToolButton()
        add_hbar_chart.connect("clicked", self._add_chart_cb, "hbar")
        add_hbar_chart.set_tooltip(_("Horizontal Bar Chart"))
        add_hbar_chart.props.icon_name = "hbar"
        add_hbar_chart.props.group = charts_group
        toolbarbox.toolbar.insert(add_hbar_chart, -1)

        add_pie_chart = RadioToolButton()
        add_pie_chart.connect("clicked", self._add_chart_cb, "pie")
        add_pie_chart.set_tooltip(_("Pie Chart"))
        add_pie_chart.props.icon_name = "pie"
        add_pie_chart.props.group = charts_group
        add_pie_chart.set_active(True)
        toolbarbox.toolbar.insert(add_pie_chart, -1)

        self.chart_type_buttons = [add_vbar_chart,
                                   add_hbar_chart,
                                   add_pie_chart]

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        fullscreen_btn = ToolButton('view-fullscreen')
        fullscreen_btn.set_tooltip(_('Fullscreen'))
        fullscreen_btn.connect("clicked", self.__fullscreen_cb)

        toolbarbox.toolbar.insert(fullscreen_btn, -1)

        charthelp.create_help(toolbarbox.toolbar)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(True)
        toolbarbox.toolbar.insert(separator, -1)

        stopbtn = StopButton(self)
        toolbarbox.toolbar.insert(stopbtn, -1)

        self.set_toolbar_box(toolbarbox)

        # CANVAS
        paned = gtk.HPaned()
        box = gtk.VBox()
        self.box = box

        # Set the info box width to 1/3 of the screen:
        def size_allocate_cb(widget, allocation):
            paned.disconnect(self._setup_handle)
            box_width = allocation.width / 3
            box.set_size_request(box_width, -1)

        self._setup_handle = paned.connect('size_allocate',
                    size_allocate_cb)

        scroll = gtk.ScrolledWindow()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.labels_and_values = ChartData(self)
        scroll.add(self.labels_and_values)

        self.labels_and_values.connect("label-changed", self._label_changed)
        self.labels_and_values.connect("value-changed", self._value_changed)

        box.pack_start(scroll, True, True, 0)

        paned.add1(box)

        # CHARTS AREA

        eventbox = gtk.EventBox()
        self.charts_area = ChartArea(self)
        self.charts_area.connect('size_allocate', self._chart_size_allocate)

        eventbox.modify_bg(gtk.STATE_NORMAL, _WHITE)

        eventbox.add(self.charts_area)
        paned.add2(eventbox)

        self.set_canvas(paned)

        self.show_all()

    def _add_chart_cb(self, widget, type="vbar"):
        self.current_chart = Chart(type)

        self.update_chart()

    def _chart_size_allocate(self, widget, allocation):
        self._render_chart()

    def unfullscreen(self):
        self.box.show()
        activity.Activity.unfullscreen(self)

    def __fullscreen_cb(self, button):
        self.box.hide()
        self._render_chart(fullscreen=True)
        activity.Activity.fullscreen(self)

    def _render_chart(self, fullscreen=False):
        if self.current_chart is None or self.charts_area is None:
            return

        try:
            # Resize the chart for all the screen sizes
            xpos, ypos, width, height = self.get_allocation()

            if fullscreen:
                new_width = width
                new_height = height

            if not fullscreen:
                sxpos, sypos, width, height = self.charts_area.get_allocation()

                new_width = width - 40
                new_height = height - 40

            self.current_chart.width = new_width
            self.current_chart.height = new_height

            # Set options
            self.current_chart.set_color_scheme(color=self.chart_color)
            self.current_chart.set_line_color(self.chart_line_color)

            if self.current_chart.type == "pie":
                self.current_chart.render(self)
            else:
                self.current_chart.render()
            self.charts_area.queue_draw()

        except (ZeroDivisionError, ValueError):
            pass

        return False

    def _update_chart_data(self):
        if self.current_chart is None:
            return
        self.current_chart.data_set(self.chart_data)
        self._update_chart_labels()

    def _set_chart_title(self, widget):
        self._update_chart_labels(title=widget.get_text())

    def _update_chart_labels(self, title=""):
        if self.current_chart is None:
            return

        if not title and self.metadata["title"]:
            title = self.metadata["title"]

        self.current_chart.set_title(title)
        self.current_chart.set_x_label(self.x_label)
        self.current_chart.set_y_label(self.y_label)
        self._render_chart()

    def update_chart(self):
        if self.current_chart:
            self.current_chart.data_set(self.chart_data)
            self.current_chart.set_title(self.metadata["title"])
            self.current_chart.set_x_label(self.x_label)
            self.current_chart.set_y_label(self.y_label)
            self._render_chart()

    def _label_changed(self, treeview, path, new_label):
        path = int(path)
        self.chart_data[path] = (new_label, self.chart_data[path][1])
        self._update_chart_data()

    def _value_changed(self, treeview, path, new_value):
        path = int(path)
        self.chart_data[path] = (self.chart_data[path][0], float(new_value))
        self._update_chart_data()

    def _set_h_label(self, widget):
        new_text = widget.get_text()

        if new_text != self.h_label._text:
            self.x_label = new_text
            self._update_chart_labels()

    def _set_v_label(self, widget):
        new_text = widget.get_text()

        if new_text != self.v_label._text:
            self.y_label = new_text
            self._update_chart_labels()

    def _set_chart_color(self, widget, pspec):
        self.chart_color = utils.rgb2html(widget.get_color())
        self._render_chart()

    def _set_chart_line_color(self, widget, pspec):
        self.chart_line_color = utils.rgb2html(widget.get_color())
        self._render_chart()

    def _object_chooser(self, mime_type, type_name):
        chooser = ObjectChooser()
        matches_mime_type = False

        response = chooser.run()
        if response == gtk.RESPONSE_ACCEPT:
            jobject = chooser.get_selected_object()
            metadata = jobject.metadata
            file_path = jobject.file_path

            if metadata['mime_type'] == mime_type:
                matches_mime_type = True

            else:
                alert = Alert()

                alert.props.title = _('Invalid object')
                alert.props.msg = \
                       _('The selected object must be a %s file' % (type_name))

                ok_icon = Icon(icon_name='dialog-ok')
                alert.add_button(gtk.RESPONSE_OK, _('Ok'), ok_icon)
                ok_icon.show()

                alert.connect('response', lambda a, r: self.remove_alert(a))

                self.add_alert(alert)

                alert.show()

        return matches_mime_type, file_path, metadata['title']

    def _graph_from_reader(self, reader):
        self.labels_and_values.model.clear()
        self.chart_data = []

        chart_data = reader.get_chart_data()
        horizontal, vertical = reader.get_labels_name()

        # Load the data
        for row  in chart_data:
            self._add_value(None,
                            label=row[0], value=float(row[1]))

            self.update_chart()

    def _add_value(self, widget, label="", value="0.0"):
        data = (label, float(value))
        if not data in self.chart_data:
            pos = self.labels_and_values.add_value(label, value)
            self.chart_data.insert(pos, data)
            self._update_chart_data()

    def _remove_value(self, widget):
        path = self.labels_and_values.remove_selected_value()
        del self.chart_data[path]
        self._update_chart_data()

    def __import_freespace_cb(self, widget):
            reader = FreeSpaceReader()
            self._graph_from_reader(reader)

    def __import_journal_cb(self, widget):
        reader = JournalReader()
        self._graph_from_reader(reader)

    def __import_turtle_cb(self, widget):
        matches_mime_type, file_path, title = self._object_chooser(
            'application/x-turtle-art', _('Turtle'))
        if matches_mime_type:
            reader = TurtleReader(file_path)
            self._graph_from_reader(reader)

    def _save_as_image(self, widget):
        if self.current_chart:
            jobject = datastore.create()

            jobject.metadata['title'] = self.metadata["title"]
            jobject.metadata['mime_type'] = "image/png"

            self.current_chart.as_png(_CHART_FILE)
            jobject.set_file_path(_CHART_FILE)

            datastore.write(jobject)

    def load_from_file(self, f):
        try:
            data = simplejson.load(f)
        finally:
            f.close()

        self.metadata["title"] = data['title']
        self.x_label = data['x_label']
        self.y_label = data['y_label']
        self.chart_color = data['chart_color']
        self.chart_line_color = data['chart_line_color']
        self.current_chart.type = data['current_chart.type']
        chart_data = data['chart_data']

        # Update charts buttons
        _type = data["current_chart.type"]
        if _type == "vbar":
            self.chart_type_buttons[0].set_active(True)

        elif _type == "hbar":
            self.chart_type_buttons[1].set_active(True)

        elif _type == "line":
            self.chart_type_buttons[2].set_active(True)

        elif _type == "pie":
            self.chart_type_buttons[3].set_active(True)

        #load the data
        for row  in chart_data:
            self._add_value(None, label=row[0], value=float(row[1]))

        self.update_chart()

    def write_file(self, file_path):
        self.metadata['mime_type'] = "application/x-chart-activity"
        if self.current_chart:

            data = {}
            data['title'] = self.metadata["title"]
            data['x_label'] = self.x_label
            data['y_label'] = self.y_label
            data['chart_color'] = self.chart_color
            data['chart_line_color'] = self.chart_line_color
            data['current_chart.type'] = self.current_chart.type
            data['chart_data'] = self.chart_data

            f = open(file_path, 'w')
            try:
                simplejson.dump(data, f)
            finally:
                f.close()

    def read_file(self, file_path):
        f = open(file_path, 'r')
        self.load_from_file(f)
Ejemplo n.º 4
0
class DashboardActivity(activity.Activity):
    def __init__(self, handle):

        activity.Activity.__init__(self, handle)

        self.current_chart = None
        self.x_label = ""
        self.y_label = ""
        self.chart_data = []
        self.mime_types = [
            'image/bmp', 'image/gif', 'image/jpeg', 'image/png', 'image/tiff',
            'application/pdf', 'application/vnd.olpc-sugar', 'application/rtf',
            'text/rtf', 'application/epub+zip', 'text/html',
            'application/x-pdf'
        ]
        self.is_updated = False

        # toolbar with the new toolbar redesign
        toolbar_box = ToolbarBox()

        activity_button = ActivityToolbarButton(self)
        toolbar_box.toolbar.insert(activity_button, 0)
        activity_button.show()

        refresh_button = ToolButton('view-refresh')
        refresh_button.set_tooltip_text(_("Refresh Data"))
        refresh_button.connect('clicked', self._load_data)
        toolbar_box.toolbar.insert(refresh_button, -1)
        refresh_button.show()

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_expand(True)
        toolbar_box.toolbar.insert(separator, -1)
        separator.show()

        stop_button = StopButton(self)
        toolbar_box.toolbar.insert(stop_button, -1)
        stop_button.show()

        self.set_toolbar_box(toolbar_box)
        toolbar_box.show()

        # notify when activity is back in focus
        self.connect('notify::active', self._notify_active_cb)

        # Detect if device is a XO
        if os.path.exists('/etc/olpc-release') or \
           os.path.exists('/sys/power/olpc-pm'):
            COLUMN_SPACING = 1
            STATS_WIDTH = 30
            TP_WIDTH = 45
            HMAP_WIDTH = 90
        else:
            COLUMN_SPACING = 2
            STATS_WIDTH = 50
            TP_WIDTH = 75
            HMAP_WIDTH = 150

        # ScrolledWindow as the main container
        scrolled_window_main = Gtk.ScrolledWindow()
        scrolled_window_main.set_can_focus(False)
        scrolled_window_main.set_policy(Gtk.PolicyType.AUTOMATIC,
                                        Gtk.PolicyType.AUTOMATIC)
        scrolled_window_main.set_shadow_type(Gtk.ShadowType.NONE)
        scrolled_window_main.show()
        self.set_canvas(scrolled_window_main)

        grid = Gtk.Grid(column_spacing=6, row_spacing=3.5)
        grid.set_border_width(20)
        grid.set_halign(Gtk.Align.CENTER)
        scrolled_window_main.add_with_viewport(grid)

        # VBoxes for total activities, journal entries and total files
        vbox_total_activities = Gtk.VBox()
        vbox_journal_entries = Gtk.VBox()
        vbox_total_contribs = Gtk.VBox()
        vbox_tree = Gtk.VBox()
        vbox_heatmap = Gtk.VBox()
        self.vbox_pie = Gtk.VBox()

        eb_total_activities = Gtk.EventBox()
        eb_journal_entries = Gtk.EventBox()
        eb_total_contribs = Gtk.EventBox()
        eb_heatmap = Gtk.EventBox()
        eb_tree = Gtk.EventBox()
        eb_pie = Gtk.EventBox()

        eb_total_activities.add(vbox_total_activities)
        eb_journal_entries.add(vbox_journal_entries)
        eb_total_contribs.add(vbox_total_contribs)
        eb_pie.add(self.vbox_pie)
        eb_tree.add(vbox_tree)

        # change eventbox color
        eb_total_activities.modify_bg(Gtk.StateType.NORMAL,
                                      Gdk.color_parse("#ffffff"))
        eb_journal_entries.modify_bg(Gtk.StateType.NORMAL,
                                     Gdk.color_parse("#ffffff"))
        eb_total_contribs.modify_bg(Gtk.StateType.NORMAL,
                                    Gdk.color_parse("#ffffff"))
        eb_heatmap.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse("#ffffff"))
        eb_pie.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse("#ffffff"))
        eb_tree.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse("#ffffff"))

        label_dashboard = Gtk.Label()
        text_dashboard = "<b>{0}</b>".format(_("Dashboard"))
        label_dashboard.set_markup(text_dashboard)

        # label for total activities
        label_TA = Gtk.Label()
        text_TA = "<b>{0}</b>".format(_("Activities Installed"))
        label_TA.set_markup(text_TA)
        vbox_total_activities.add(label_TA)

        self.label_total_activities = Gtk.Label()
        vbox_total_activities.add(self.label_total_activities)

        # label for total journal entries
        label_JE = Gtk.Label()
        text_JE = "<b>{0}</b>".format(_("Journal Entries"))
        label_JE.set_markup(text_JE)
        vbox_journal_entries.add(label_JE)

        self.label_journal_entries = Gtk.Label()
        vbox_journal_entries.add(self.label_journal_entries)

        # label for files
        label_CE = Gtk.Label()
        text_CE = "<b>{0}</b>".format(_("Total Files"))
        label_CE.set_markup(text_CE)
        vbox_total_contribs.add(label_CE)

        # label for pie
        label_PIE = Gtk.Label()
        text_PIE = "<b>{0}</b>".format(_("Most used activities"))
        label_PIE.set_markup(text_PIE)
        self.vbox_pie.pack_start(label_PIE, False, True, 5)

        self.label_contribs = Gtk.Label()
        vbox_total_contribs.add(self.label_contribs)

        # pie chart
        self.labels_and_values = ChartData(self)
        self.eventbox = Gtk.EventBox()
        self.charts_area = ChartArea(self)
        self.charts_area.connect('size-allocate', self._chart_size_allocate_cb)
        self.eventbox.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse("white"))
        self.eventbox.add(self.charts_area)
        self.vbox_pie.pack_start(self.eventbox, True, True, 0)
        self.eventbox.connect('button-press-event', self._pie_opened)
        self.charts_area.set_tooltip_text(_("Click for more information"))

        # pie chart window
        self.window = Gtk.Window(Gtk.WindowType.TOPLEVEL)
        self.window.set_border_width(2)
        self.window.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        self.window.set_decorated(True)
        self.window.set_resizable(False)
        self.window.set_modal(True)
        self.window.set_keep_above(True)
        self.window.set_size_request(800, 600)
        self.window.set_title("Pie Chart")
        self.window.connect('delete-event', self._hide_window)

        eb_image_holder = Gtk.EventBox()
        eb_image_holder.modify_bg(Gtk.StateType.NORMAL,
                                  Gdk.color_parse("ffffff"))
        self.window.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse("#282828"))

        vbox_image = Gtk.VBox()
        eb_image_holder.add(vbox_image)

        # scrolled window for details window
        scrolled_window = Gtk.ScrolledWindow()
        scrolled_window.set_can_focus(False)
        scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
                                   Gtk.PolicyType.AUTOMATIC)
        scrolled_window.set_shadow_type(Gtk.ShadowType.NONE)
        scrolled_window.show()

        # load pie image
        # not using get_activity_root for now
        self.image = Gtk.Image()
        vbox_image.add(self.image)

        self.vbox_holder = Gtk.VBox()
        self.vbox_holder.pack_start(eb_image_holder, True, True, 0)
        self.vbox_holder.pack_start(self.labels_and_values, False, False, 0)
        self.window.add(scrolled_window)
        scrolled_window.add_with_viewport(self.vbox_holder)

        reader = JournalReader()
        self._graph_from_reader(reader)
        self.current_chart = Chart("pie")
        self.update_chart()

        # font
        font_main = Pango.FontDescription("Granada 12")
        label_JE.modify_font(font_main)
        label_CE.modify_font(font_main)
        label_TA.modify_font(font_main)

        font_actual = Pango.FontDescription("12")
        self.label_journal_entries.modify_font(font_actual)
        self.label_total_activities.modify_font(font_actual)
        self.label_contribs.modify_font(font_actual)
        label_dashboard.modify_font(font_actual)

        self.treeview_list = []
        self.files_list = []
        self.old_list = []
        self.heatmap_list = []
        self.journal_entries = 0

        # treeview for Journal entries
        self.liststore = Gtk.ListStore(str, str, str, object, str,
                                       datastore.DSMetadata, str, str)
        self.treeview = Gtk.TreeView(self.liststore)
        self.treeview.set_headers_visible(False)
        self.treeview.set_grid_lines(Gtk.TreeViewGridLines.HORIZONTAL)
        self._load_data()

        for i, col_title in enumerate(["Recently Opened Activities"]):

            renderer_title = Gtk.CellRendererText()
            renderer_time = Gtk.CellRendererText()
            icon_renderer = CellRendererActivityIcon()

            renderer_title.set_property('ellipsize', Pango.EllipsizeMode.END)
            renderer_title.set_property('ellipsize-set', True)

            column1 = Gtk.TreeViewColumn("Icon")
            column1.pack_start(icon_renderer, True)
            column1.add_attribute(icon_renderer, 'file-name', 1)
            column1.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
            column1.add_attribute(icon_renderer, 'xo-color', 3)
            column2 = Gtk.TreeViewColumn(col_title, renderer_title, text=0)
            column2.set_min_width(200)
            column3 = Gtk.TreeViewColumn(col_title, renderer_time, text=6)

            self.treeview.set_tooltip_column(0)
            self.treeview.append_column(column1)
            self.treeview.append_column(column2)
            self.treeview.append_column(column3)

        # combobox for sort selection
        self.cbox_store = Gtk.ListStore(str)
        cbox_entries = [_("Newest"), _("Files"), _("Oldest")]

        for item in cbox_entries:
            self.cbox_store.append([item])

        self.combobox = Gtk.ComboBox.new_with_model(self.cbox_store)
        self.combobox.set_halign(Gtk.Align.END)
        self.combobox.connect('changed', self._on_name_combo_changed_cb)
        renderer_text = Gtk.CellRendererText()
        self.combobox.pack_start(renderer_text, True)
        self.combobox.add_attribute(renderer_text, "text", 0)
        self.combobox.set_active(0)

        self._add_to_treeview(self.treeview_list)

        selected_row = self.treeview.get_selection()
        selected_row.connect('changed', self._item_select_cb)

        scrolled_window = Gtk.ScrolledWindow()
        scrolled_window.set_can_focus(False)
        scrolled_window.set_policy(Gtk.PolicyType.NEVER,
                                   Gtk.PolicyType.AUTOMATIC)
        scrolled_window.set_shadow_type(Gtk.ShadowType.NONE)
        scrolled_window.show()

        hbox_tree2 = Gtk.HBox()
        text_treeview = "<b>{0}</b>".format(_("Journal Entries"))
        self.label_treeview = Gtk.Label()
        self.label_treeview.set_markup(text_treeview)
        hbox_tree2.pack_start(self.label_treeview, False, True, 10)
        hbox_tree2.pack_start(self.combobox, True, True, 10)

        vbox_tree.pack_start(hbox_tree2, False, False, 5)
        scrolled_window.add_with_viewport(self.treeview)

        # label for recent activities
        label_rec = Gtk.Label(expand=False)
        text_treeview = "{0}".format(_("Recently Opened Activities"))
        label_rec.set_markup(text_treeview)

        vbox_tree.add(scrolled_window)

        # heatmap
        label_heatmap = Gtk.Label()
        text_HE = "<b>{0}</b>".format(_("User Activity"))
        label_heatmap.set_markup(text_HE)
        grid_heatmap = Gtk.Grid(column_spacing=COLUMN_SPACING, row_spacing=2)
        grid_heatmap.set_halign(Gtk.Align.CENTER)
        vbox_heatmap.pack_start(label_heatmap, False, True, 5)
        vbox_heatmap.pack_start(grid_heatmap, False, True, 5)

        self.dates, self.dates_a, months = self._generate_dates()
        self._build_heatmap(grid_heatmap, self.dates, self.dates_a, months)

        eb_heatmap.add(vbox_heatmap)

        # add views to grid
        grid.attach(label_dashboard, 1, 2, 1, 1)
        grid.attach_next_to(eb_total_activities, label_dashboard,
                            Gtk.PositionType.BOTTOM, STATS_WIDTH, 35)
        grid.attach_next_to(eb_journal_entries, eb_total_activities,
                            Gtk.PositionType.RIGHT, STATS_WIDTH, 35)
        grid.attach_next_to(eb_total_contribs, eb_journal_entries,
                            Gtk.PositionType.RIGHT, STATS_WIDTH, 35)
        grid.attach_next_to(eb_heatmap, eb_total_activities,
                            Gtk.PositionType.BOTTOM, HMAP_WIDTH, 75)
        grid.attach_next_to(eb_tree, eb_heatmap, Gtk.PositionType.BOTTOM,
                            TP_WIDTH, 90)
        grid.attach_next_to(eb_pie, eb_tree, Gtk.PositionType.RIGHT, TP_WIDTH,
                            90)

        grid.show_all()

    def _ds_updated(self, i):
        self.is_updated = True

    def _load_data(self, widget=None):
        del self.treeview_list[:]
        del self.files_list[:]
        del self.old_list[:]
        del self.heatmap_list[:]

        dsobjects, journal_entries = datastore.find({})
        for dsobject in dsobjects:
            new = []
            new.append(dsobject.metadata['title'])
            new.append(misc.get_icon_name(dsobject.metadata))
            new.append(dsobject.metadata['activity_id'])
            new.append(profile.get_color())
            new.append(dsobject.get_object_id())
            new.append(dsobject.metadata)
            new.append(misc.get_date(dsobject.metadata))
            new.append(dsobject.metadata['mtime'])
            dsobject.metadata.connect('updated', self._ds_updated)
            self.treeview_list.append(new)
            self.old_list.append(new)

            # determine if a file
            if dsobject.metadata['mime_type'] in self.mime_types:
                new2 = []
                new2.append(dsobject.metadata['title'])
                new2.append(misc.get_icon_name(dsobject.metadata))
                new2.append(dsobject.metadata['activity_id'])
                new2.append(profile.get_color())
                new2.append(dsobject.get_object_id())
                new2.append(dsobject.metadata)
                new2.append(misc.get_date(dsobject.metadata))
                new2.append(dsobject.metadata['mtime'])
                self.files_list.append(new2)

            self.old_list = sorted(self.old_list, key=lambda x: x[7])
            self.journal_entries = journal_entries
            self._add_to_treeview(self.treeview_list)

            # get number of activities installed
            registry = bundleregistry.get_registry()

            self.label_total_activities.set_text(str(len(registry)))
            self.label_journal_entries.set_text(str(self.journal_entries))
            self.label_contribs.set_text(str(len(self.files_list)))

    def _notify_active_cb(self, widget, pspec):
        # refresh data when activity is active
        if self.props.active and self.is_updated:
            self._load_data()
            self.is_updated = False

    def _pie_opened(self, widget, event):
        self.update_chart(300)
        self.vbox_holder.pack_start(self.labels_and_values, False, False, 0)
        pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
            "/tmp/screenshot.png", 800, 550, True)
        self.image.set_from_pixbuf(pixbuf)
        self.window.show()
        self.window.show_all()

    def _hide_window(self, *args):
        self.vbox_holder.remove(self.labels_and_values)
        self.window.hide()
        self.update_chart(0)
        return Gtk.true

    def _build_heatmap(self, grid, dates, dates_a, months):
        j = 1
        k = 1
        counter_days = 0
        counter_weeks = 0
        week_list = [0, 5, 9, 13, 18, 22, 26, 31, 35, 39, 44, 49]
        months_dict = {}

        # populate dictionary
        for i, item in enumerate(week_list):
            months_dict[item] = months[i]

        for i in range(0, 365):
            if (i % 7 == 0):
                j = j + 1
                k = 0
            k = k + 1
            count = 0
            for x in range(0, len(self.old_list)):
                date = self.old_list[x][7][:-16]
                if date == dates[i]:
                    count = count + 1
            box = HeatMapBlock(dates_a[i], count, i)
            box.connect('on-clicked', self._on_clicked_cb)
            lab_days = Gtk.Label()
            lab_months = Gtk.Label()

            # for weekdays
            if (k % 2 == 0 and counter_days < 3):
                day = ''
                if (counter_days == 0):
                    day = dates_a[8][:-13]
                    lab_days.set_text(_(day))
                if (counter_days == 1):
                    day = dates_a[10][:-13]
                    lab_days.set_text(_(day))
                if (counter_days == 2):
                    day = dates_a[12][:-13]
                    lab_days.set_text(_(day))

                grid.attach(lab_days, 0, k, 1, 1)
                counter_days = counter_days + 1

            # for months
            if (k % 4 == 0 and counter_weeks < 54):
                for key, value in months_dict.items():
                    if counter_weeks == key:
                        lab_months.set_text(str(value))

                if counter_weeks in week_list:
                    grid.attach(lab_months, j, 0, 2, 1)

                counter_weeks = counter_weeks + 1

            grid.attach(box, j, k, 1, 1)

    def _on_clicked_cb(self, i, index):
        del self.heatmap_list[:]
        for y in range(0, len(self.old_list)):
            date = self.old_list[y][7][:-16]
            if date == self.dates[index]:
                self.heatmap_list.append(self.old_list[y])

        model = self.combobox.get_model()
        size = model.get_value(model[-1].iter, 0)
        if len(size) == 10:
            model.remove(model[-1].iter)
        # self.cbox_store.remove(model[-1].iter)
        self.cbox_store.append([self.dates[index]])
        self.combobox.set_active(3)
        self._add_to_treeview(self.heatmap_list)

    def _generate_dates(self):
        year = datetime.date.today().year

        dt = datetime.datetime(year, 1, 1)
        end = datetime.datetime(year, 12, 31, 23, 59, 59)
        step = datetime.timedelta(days=1)

        result = []
        result_a = []
        months = []

        while dt < end:
            result_a.append(dt.strftime('%a, %b %d %Y'))
            result.append(dt.strftime('%Y-%m-%d'))
            dt += step

        for i in range(1, 13):
            month_abre = datetime.date(year, i, 1).strftime('%b')
            months.append(month_abre)

        return result, result_a, months

    def _add_to_treeview(self, tlist):
        self.liststore.clear()
        for item in tlist:
            self.liststore.append(item)

    def _on_name_combo_changed_cb(self, combo):
        tree_iter = combo.get_active_iter()
        if tree_iter is not None:
            model = combo.get_model()
            selected_item = model[tree_iter][0]
            if selected_item == "Files":
                self._add_to_treeview(self.files_list)
            elif selected_item == "Newest":
                self._add_to_treeview(self.treeview_list)
            elif selected_item == "Oldest":
                self._add_to_treeview(self.old_list)
            else:
                self._add_to_treeview(self.heatmap_list)

    def _item_select_cb(self, selection):
        model, row = selection.get_selected()

        if row is not None:
            metadata = model[row][5]
            bundle_id = metadata.get('activity', '')
            launch_bundle(bundle_id, model[row][4])

    def _chart_size_allocate_cb(self, widget, allocation):
        self._render_chart()

    def _render_chart(self, extra_size=0):
        if self.current_chart is None or self.charts_area is None:
            return

        # Resize the chart for all the screen sizes
        alloc = self.vbox_pie.get_allocation()
        new_width = alloc.width + extra_size
        new_height = alloc.height + extra_size

        self.current_chart.width = new_width
        self.current_chart.height = new_height

        try:
            if self.current_chart.type == "pie":
                self.current_chart.render(self)
            else:
                self.current_chart.render()
            self.charts_area.queue_draw()
            surface = self.charts_area.get_surface()
            surface.write_to_png('/tmp/screenshot.png')
        except (ZeroDivisionError, ValueError):
            pass

        return False

    def _graph_from_reader(self, reader):
        self.labels_and_values.model.clear()
        self.chart_data = []

        chart_data = reader.get_chart_data()

        # Load the data
        for row in chart_data:
            self._add_value(None, label=row[0], value=float(row[1]))

            self.update_chart()

    def _add_value(self, widget, label="", value="0.0"):
        data = (label, float(value))
        if data not in self.chart_data:
            pos = self.labels_and_values.add_value(label, value)
            self.chart_data.insert(pos, data)
            self._update_chart_data()

    def update_chart(self, extra_size=0):
        if self.current_chart:
            self.current_chart.data_set(self.chart_data)
            self.current_chart.set_x_label(self.x_label)
            self.current_chart.set_y_label(self.y_label)
            self._render_chart(extra_size)

    def _update_chart_data(self):
        if self.current_chart is None:
            return
        self.current_chart.data_set(self.chart_data)
        self._update_chart_labels()

    def _update_chart_labels(self, title=""):
        if self.current_chart is None:
            return
        self.current_chart.set_title(title)
        self.current_chart.set_x_label(self.x_label)
        self.current_chart.set_y_label(self.y_label)
        self._render_chart()