# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# Mobius Forensic Toolkit
# Copyright (C) 2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024 Eduardo Aguiar
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
import threading
import traceback

import mobius
import pymobius
import pymobius.ant.evidence
from gi.repository import GLib
from gi.repository import GdkPixbuf
from gi.repository import Gtk

from common import count_evidences
from common import get_icon_path
from generic_view import GenericView
from metadata import *

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# Constants
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
ANT_ID = pymobius.ant.evidence.ANT_ID
MODEL = pymobius.ant.evidence.MODEL


# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Evidence view
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class EvidenceView(object):

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Initialize widget
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def __init__(self):
        mediator = pymobius.mediator.copy()
        self.__itemlist = []
        self.__running_items = {}

        self.name = f'{EXTENSION_NAME} v{EXTENSION_VERSION}'
        icon_path = mediator.call('extension.get-icon-path', EXTENSION_ID)
        self.icon_data = open(icon_path, 'rb').read()

        # read available views
        self.__views = {}

        for info in MODEL:
            view_id = info.get('view_id')
            evidence_type = info.get('id')

            if view_id:
                c = mobius.core.get_resource_value(f"evidence.widget.{view_id}")
                view = c(self)

            else:
                view = GenericView(self, info)

            self.__views[evidence_type] = view

        # build widget
        self.__widget = mediator.call('ui.new-widget', 'container')
        self.__widget.show()

        self.__view_selector = mediator.call('ui.new-widget', 'view-selector')
        self.__view_selector.set_control(self)
        self.__view_selector.show()
        self.__widget.add(self.__view_selector.get_ui_widget())

        self.__list_view = ListView(self)
        self.__view_selector.add('list-view', self.__list_view)

        self.__icon_view = IconView(self)
        self.__view_selector.add('icon-view', self.__icon_view)

        self.__close_toolbutton = Gtk.ToolButton.new()
        self.__close_toolbutton.set_icon_name('window-close')
        self.__close_toolbutton.set_tooltip_text("Close current view")
        self.__close_toolbutton.set_sensitive(False)
        self.__close_toolbutton.connect("clicked", self.__on_close_view)
        self.__close_toolbutton.show()

        toolbar = self.__view_selector.get_toolbar()
        toolbar.insert(self.__close_toolbutton, -1)

        # populate view selector
        toolbar = self.__view_selector.get_toolbar()
        self.__toolbar_separator_pos = -1
        self.__active_views = mobius.core.get_config('evidence-viewer.active-views') or []

        for view_id in self.__active_views[:]:
            view = self.__views.get(view_id)

            if view:
                if self.__toolbar_separator_pos == -1:
                    self.__toolbar_separator_pos = toolbar.get_n_items()
                    toolitem = Gtk.SeparatorToolItem()
                    toolitem.show()
                    toolbar.insert(toolitem, -1)

                self.__view_selector.add(view_id, view)

            else:
                self.__active_views.remove(view_id)

        # set initial message
        self.__widget.set_warning_label('Select item(s) to view evidences')

        # connect to events
        self.__event_uid_1 = mobius.core.subscribe('resource-added', self.__on_resource_added)
        self.__event_uid_2 = mobius.core.subscribe('resource-removed', self.__on_resource_removed)

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Get ui widget
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def get_ui_widget(self):
        return self.__widget.get_ui_widget()

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief on_destroy view
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def on_destroy(self):
        for view in self.__view_selector:
            if hasattr(view, 'on_destroy'):
                view.on_destroy()

        self.__save_active_views()

        mobius.core.unsubscribe(self.__event_uid_1)
        mobius.core.unsubscribe(self.__event_uid_2)

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Set data to be viewed
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def set_data(self, itemlist):
        self.__itemlist = itemlist

        if self.__itemlist:
            try:
                self.__retrieve_data()
            except Exception as e:
                self.__widget.set_warning_label(str(e))
                mobius.core.logf(f"WRN {str(e)}\n{traceback.format_exc()}")

        else:
            self.__widget.set_warning_label('Select item(s) to view evidences')

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Run ANT
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def __retrieve_data(self):
        items = []

        # add items to processing queue, if necessary
        try:
            for item in self.__itemlist:

                if item not in self.__running_items and not item.has_ant(ANT_ID):
                    ant = pymobius.ant.evidence.Ant(item)
                    t = threading.Thread(target=self.__thread_begin, args=(ant, item), daemon=True)
                    t.start()
                    self.__running_items[item] = t

                if item in self.__running_items:
                    items.append(item)

        except Exception as e:
            mobius.core.logf(f"WRN {str(e)}\n{traceback.format_exc()}")
            self.__widget.set_warning_label(str(e))
            return

        # if items are running, show message. Otherwise, show data
        if len(items) == 1:
            item = items[0]
            self.__widget.set_warning_label(f"Retrieving evidences. Item: {item.name}...")

        elif len(items) > 0:
            text = '\n'.join(item.name for item in items)
            self.__widget.set_warning_label(f"Retrieving evidences. Items: {text}")

        else:
            self.__view_selector.set_data(self.__itemlist)
            self.__widget.show_content()

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Thread begin code
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def __thread_begin(self, ant, item):
        ant.run()

        GLib.idle_add(self.__thread_end, item)

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Thread end code
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def __thread_end(self, item):
        self.__running_items.pop(item, None)
        self.__retrieve_data()

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Handle on_view_activated event
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def on_view_activated(self, view_id):
        view = self.__views.get(view_id)
        if not view:
            return

        # add separator if it is the first item
        if self.__toolbar_separator_pos == -1:
            toolbar = self.__view_selector.get_toolbar()
            self.__toolbar_separator_pos = toolbar.get_n_items()

            toolitem = Gtk.SeparatorToolItem()
            toolitem.show()
            toolbar.insert(toolitem, -1)

        # add view to view_selector if necessary
        if not self.__view_selector.has_view(view_id):
            self.__active_views.append(view_id)
            self.__view_selector.add(view_id, view)

        # set as current view
        self.__view_selector.set_current_view(view_id)

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Handle view_selector on_view_changed event
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def on_view_changed(self, view):
        flag_can_close = bool(view) and (view.id not in ('list-view', 'icon-view'))
        self.__close_toolbutton.set_sensitive(flag_can_close)

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Handle on_reload event
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def on_reload(self):

        # show confirmation dialog, if necessary
        if any(i for i in self.__itemlist if i.has_ant(ANT_ID)):
            dialog = mobius.ui.message_dialog(mobius.ui.MESSAGE_DIALOG_TYPE_QUESTION)
            dialog.text = "You are about to reload evidences. Are you sure?"
            dialog.add_button(mobius.ui.BUTTON_YES)
            dialog.add_button(mobius.ui.BUTTON_NO)
            dialog.set_default_response(mobius.ui.BUTTON_NO)
            rc = dialog.run()

            if rc != mobius.ui.BUTTON_YES:
                return

        # reload evidences
        for item in self.__itemlist:
            item.reset_ant(ANT_ID)

        self.__retrieve_data()

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Handle close_button clicked event
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def __on_close_view(self, toolbutton, *args):
        view_id, view = self.__view_selector.get_current_view()

        self.__remove_view_from_view_selector(view_id)
        self.__active_views.remove(view_id)
        self.__save_active_views()

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Handle resource-added event
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def __on_resource_added(self, resource_id, resource, *args):
        if not resource_id.startswith('evidence.widget.'):
            return

        item_id = resource.id

        # Add view
        view = resource.value(self)
        view.id = item_id

        self.__views[item_id] = view
        self.__list_view.set_data(self.__itemlist)
        self.__icon_view.set_data(self.__itemlist)

        # Check if view is active
        try:
            idx = self.__active_views.index(item_id)
        except ValueError as e:
            idx = -1

        if idx == -1:
            return

        # Add toolbar separator, if necessary
        toolbar = self.__view_selector.get_toolbar()

        if self.__toolbar_separator_pos == -1:
            self.__toolbar_separator_pos = toolbar.get_n_items()
            toolitem = Gtk.SeparatorToolItem()
            toolitem.show()
            toolbar.insert(toolitem, -1)

        # Insert view into the toolbar
        pos = self.__toolbar_separator_pos + 1
        item_idx = -1

        while pos < toolbar.get_n_items() and item_idx < idx:
            item = toolbar.get_nth_item(pos)
            item_idx = self.__active_views.index(item.view_id)

            if item_idx < idx:
                pos += 1

        self.__view_selector.add(item_id, view, pos)

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Handle resource-removed event
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def __on_resource_removed(self, resource_id):
        if resource_id.startswith('evidence.widget.'):
            item_id = resource_id.rsplit('.', 1)[1]
            self.__views.pop(item_id, None)
            self.__list_view.set_data(self.__itemlist)
            self.__icon_view.set_data(self.__itemlist)
            self.__remove_view_from_view_selector(item_id)

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Remove view from view_selector
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def __remove_view_from_view_selector(self, view_id):
        self.__view_selector.remove(view_id)

        # remove toolbar separator if there are no more items
        toolbar = self.__view_selector.get_toolbar()

        if self.__toolbar_separator_pos != -1 and self.__toolbar_separator_pos == toolbar.get_n_items() - 1:
            sep = toolbar.get_nth_item(self.__toolbar_separator_pos)
            toolbar.remove(sep)
            self.__toolbar_separator_pos = -1

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Save active views list
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def __save_active_views(self):
        transaction = mobius.core.new_config_transaction()
        mobius.core.set_config('evidence-viewer.active-views', self.__active_views)
        transaction.commit()


# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief View: icon
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
IV_ICON, IV_TYPE, IV_NAME, IV_LABEL, IV_TOOLTIP = range(5)


class IconView(object):

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Initialize widget
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def __init__(self, control):
        mediator = pymobius.mediator.copy()
        self.__category_icons = {}
        self.__factory = mediator.call('ui.new-factory')
        self.__control = control
        self.name = 'Icon View'

        path = mediator.call('extension.get-resource-path', EXTENSION_ID, 'icon-view.png')
        self.icon_data = open(path, 'rb').read()

        # build widget
        self.__widget = Gtk.ScrolledWindow()
        self.__widget.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)

        self.__model = Gtk.ListStore.new([GdkPixbuf.Pixbuf, str, str, str, str])
        self.__model.set_sort_column_id(IV_NAME, Gtk.SortType.ASCENDING)

        self.__iconview = Gtk.IconView.new_with_model(self.__model)
        self.__iconview.set_pixbuf_column(IV_ICON)
        self.__iconview.set_markup_column(IV_LABEL)
        self.__iconview.set_tooltip_column(IV_TOOLTIP)
        self.__iconview.set_columns(-1)
        self.__iconview.set_selection_mode(Gtk.SelectionMode.MULTIPLE)
        self.__iconview.connect('item-activated', self.__on_icon_activated)
        self.__iconview.show()
        self.__widget.add(self.__iconview)

        # Add evidence icons
        for info in MODEL:
            evidence_type = info.get('id')
            name = info.get('name')
            description = info.get('description') or name
            label = name + '\n(0)'

            path = get_icon_path(evidence_type)
            icon = GdkPixbuf.Pixbuf.new_from_file_at_size(path, 64, 64)
            tooltip = description

            self.__model.append((icon, evidence_type, name, label, tooltip))

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief get ui widget
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def get_ui_widget(self):
        return self.__widget

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief set data to be viewed
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def set_data(self, itemlist):
        totals = count_evidences(itemlist)

        for row in self.__model:
            evidence_type = row[IV_TYPE]
            name = row[IV_NAME]
            count = totals.get(evidence_type, 0)
            row[IV_LABEL] = f"{name}\n({count})"

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Event: icon activated
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def __on_icon_activated(self, icon_view, path, *args):
        view_id = self.__model[path][IV_TYPE]
        self.__control.on_view_activated(view_id)


# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief View: List
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class ListView(object):

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Initialize widget
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def __init__(self, control):
        mediator = pymobius.mediator.copy()
        self.__category_icons = {}
        self.__factory = mediator.call('ui.new-factory')
        self.__control = control
        self.name = 'List View'

        path = mediator.call('extension.get-resource-path', EXTENSION_ID, 'list-view.png')
        self.icon_data = open(path, 'rb').read()

        # build widget
        self.__listview = mediator.call('ui.new-widget', 'tableview')
        self.__listview.set_control(self, 'listview')
        self.__listview.set_report_id('evidences')
        self.__listview.set_report_name('Evidences')
        self.__listview.set_report_app('%s v%s' % (EXTENSION_NAME, EXTENSION_VERSION))
        self.__listview.show()
        self.__widget = self.__listview

        column = self.__listview.add_column('icon', '', column_type='icon')

        column = self.__listview.add_column('id', 'ID')
        column.is_visible = False

        column = self.__listview.add_column('name', 'Name')
        column.is_markup = True

        column = self.__listview.add_column('count', 'Count', column_type='int')
        column = self.__listview.add_column('description', 'Description')

        # Add evidence rows to listview
        for info in MODEL:
            evidence_type = info.get('id')
            name = info.get('name')
            description = info.get('description') or name

            path = get_icon_path(evidence_type)
            icon = GdkPixbuf.Pixbuf.new_from_file_at_size(path, 32, 32)

            self.__listview.set_icon(evidence_type, icon)
            self.__listview.add_row((evidence_type, evidence_type, name, 0, description))

        # Add total row to listview
        path = mediator.call('extension.get-resource-path', EXTENSION_ID, 'total.png')
        icon_data = open(path, 'rb').read()
        image_buffer = self.__factory.new_image_buffer_from_data(icon_data, 32, 32)
        icon = image_buffer.get_ui_widget()
        self.__listview.set_icon('total', icon)
        self.__listview.add_row(('total', None, '<b>TOTAL</b>', 0, None, None))

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Get ui widget
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def get_ui_widget(self):
        return self.__widget.get_ui_widget()

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Set data to be viewed
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def set_data(self, itemlist):
        totals = count_evidences(itemlist)
        total = 0

        for row in self.__listview:
            evidence_type = row[1]

            count = totals.get(evidence_type, 0)
            total += count

            if evidence_type:
                row[3] = count

            else:
                row[3] = total

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Event: row activated
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def listview_on_row_activated(self, row_id, row_data):
        view_id = row_data[1]

        if view_id:
            self.__control.on_view_activated(view_id)

    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    # @brief Event: reload
    # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    def listview_on_reload_data(self, widget, *args):
        self.__control.on_reload()


# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Start function
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def pvt_start():
    mobius.core.add_resource('view.evidence-viewer', 'Evidence Viewer view', EvidenceView)


# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Stop function
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def pvt_stop():
    mobius.core.remove_resource('view.evidence-viewer')


# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# API initialization
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def pvt_start_api():
    pass
