'Changes workspace in a separate thread. Emits a signal
to present a \'Loading workspace\' dialog while Faraday processes
the change. If there are conflict present in the workspace, it will
show a warning before changing the workspaces.'

def change_workspace(self, workspace_name):

    def loading_workspace(action):
        'Function    to    be    called    via    GObject.idle_add    by    the    background\n                                                process.        Preconditions:    show    must    have    been    called    before    destroy\n                                                can    be    called.\n                                                '
        if ((action == 'show') and (not self.loading_dialog_raised)):
            message_string = 'Loading    workspace    {0}.    Please    wait.    \nTo    cancel,    press    Alt+F4    or    a    similar    shorcut.'.format(workspace_name)
            self.loading_dialog_raised = True
            self.loading_dialog = Gtk.MessageDialog(self.window, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.NONE, message_string)
            self.loading_dialog.set_modal(True)
            self.loading_dialog.connect('key_press_event', (lambda _, __: True))
            self.loading_dialog.connect('delete_event', (lambda _, __: self.handle_no_active_workspace()))
            self.loading_dialog.show_all()
        if (action == 'destroy'):
            self.loading_dialog.destroy()
            self.loading_dialog_raised = False
    def background_process():
        'Change    workspace.    This    function    runs    on    a    separated    thread\n                                                created    by    the    parent    function.    DO    NOT    call    any    Gtk    methods\n                                                withing    its    scope,    except    by    emiting    signals    to    the    window\n                                                '
        GObject.idle_add(loading_workspace, 'show')
        try:
            ws = super(GuiApp, self).openWorkspace(workspace_name)
            GObject.idle_add(CONF.setLastWorkspace, ws.name)
            GObject.idle_add(CONF.saveConfig)
        except Exception as e:
            GObject.idle_add(self.handle_no_active_workspace)
            getLogger('GTK').error(e)
        GObject.idle_add(loading_workspace, 'destroy')
        return True
    self.ws_sidebar.select_ws_by_name(workspace_name)
    if (self.statusbar.conflict_button_label_int > 0):
        response = self.window.show_conflicts_warning()
        if (response == Gtk.ResponseType.NO):
            self.select_active_workspace()
            return False
    thread = threading.Thread(target=background_process)
    thread.daemon = True
    thread.start()
