Example #1
0
    def triggered_show_create_plugin_menu(self):
        """


        :return:
        """
        self.create_plugin_menu = CreatePluginMenu(
            self.gui_management.gui_api, self.TabManager,
            self.gui_management.plugin_manager)

        self.create_plugin_menu.show()
Example #2
0
File: main.py Project: dani-l/PaPI
    def triggered_show_create_plugin_menu(self):
        """


        :return:
        """
        self.create_plugin_menu = CreatePluginMenu(self.gui_management.gui_api,
                                                   self.TabManager,
                                                   self.gui_management.plugin_manager )

        self.create_plugin_menu.show()
Example #3
0
File: main.py Project: dani-l/PaPI
class GUI(QMainWindow, Ui_DefaultMain):
    """
    Used to create the qt based PaPI gui.

    """
    def __init__(self, core_queue = None, gui_queue= None, gui_id = None, gui_data = None, is_parent = False, parent=None):
        """
        Init function

        :param core_queue: Queue used to send papi events to Core
        :param gui_queue: GUI queue which contains papi events for the gui
        :param gui_id: Unique ID for this gui
        :param gui_data: Contains all data for the current session
        :param parent: parent element
        :return:
        """
        super(GUI, self).__init__(parent)
        self.is_parent = is_parent

        self.setupUi(self)

        # Create a data structure for gui if it is missing
        # -------------------------------------------------- #
        if not isinstance(gui_data, DGui):
            self.gui_data = DGui()
        else:
            self.gui_data = gui_data


        # check if gui should be the parent process or core is the parent
        # start core if gui is parent
        # -------------------------------------------------- #
        self.core_process = None
        if is_parent:
            core_queue_ref = Queue()
            gui_queue_ref = Queue()
            gui_id_ref = 1
            self.core_process = Process(target = run_core_in_own_process,
                                        args=(gui_queue_ref,core_queue_ref, gui_id_ref ))
            self.core_process.start()
        else:
            if core_queue is None:
                raise Exception('Gui started with wrong arguments')
            if gui_queue is None:
                raise Exception('Gui started with wrong arguments')
            if not isinstance(gui_id, str):
                raise Exception('Gui started with wrong arguments')

            core_queue_ref = core_queue
            gui_queue_ref = gui_queue
            gui_id_ref = gui_id


        # Create the Tab Manager and the gui management unit #
        # connect some signals of management to gui          #
        # -------------------------------------------------- #
        self.TabManager = PapiTabManger(tabWigdet=self.widgetTabs, centralWidget=self.centralwidget)

        self.gui_management = GuiManagement(core_queue_ref,
                                    gui_queue_ref,
                                    gui_id_ref,
                                    self.TabManager,
                                    self.get_gui_config,
                                    self.set_gui_config)

        self.TabManager.gui_api = self.gui_management.gui_api
        self.TabManager.dGui    = self.gui_management.gui_data

        self.gui_management.gui_event_processing.added_dplugin.connect(self.add_dplugin)
        self.gui_management.gui_event_processing.removed_dplugin.connect(self.remove_dplugin)
        self.gui_management.gui_event_processing.dgui_changed.connect(self.changed_dgui)
        self.gui_management.gui_event_processing.plugin_died.connect(self.plugin_died)

        self.gui_management.gui_api.error_occured.connect(self.error_occured)

        # initialize the graphic of the gui
        # -------------------------------------------------- #
        self.gui_graphic_init()

        signal.signal(signal.SIGINT, lambda a,b: self.signal_handler(a,b))

        # List for keys that are active
        self.keysActiveList = [];


    def signal_handler(self,signal, frame):
        """
        This handler will be called, when CTRL+C is used in the console
        It will react to SIGINT Signal
        As an reaction it will close the gui by first telling the core to close and then closing the gui
        :return:
        """
        self.gui_management.gui_api.do_close_program()
        sys.exit(0)


    def gui_graphic_init(self):
        self.setWindowTitle(pc.GUI_PAPI_WINDOW_TITLE)
        # set GUI size
        self.setGeometry(self.geometry().x(),self.geometry().y(), pc.GUI_DEFAULT_WIDTH, pc.GUI_DEFAULT_HEIGHT)

        self.count = 0

        self.log = ConsoleLog(pc.GUI_PROCESS_CONSOLE_LOG_LEVEL, pc.GUI_PROCESS_CONSOLE_IDENTIFIER)

        self.log.printText(1,pc.GUI_START_CONSOLE_MESSAGE + ' .. Process id: '+str(os.getpid()))

        self.last_config = pc.PAPI_LAST_CFG_PATH

        self.in_run_mode = False


        # -------------------------------------
        # Create placeholder
        # -------------------------------------
        self.overview_menu = None
        self.create_plugin_menu = None
        self.plugin_create_dialog = None

        # -------------------------------------
        # Create menues
        # -------------------------------------
        self.plugin_create_dialog = CreatePluginDialog(self.gui_management.gui_api, self.TabManager)


        # -------------------------------------
        # Create callback functions for buttons
        # -------------------------------------
        #self.loadButton.clicked.connect(self.load_triggered)
        #self.saveButton.clicked.connect(self.save_triggered)

        # -------------------------------------
        # Create actions
        # -------------------------------------
        _translate = QtCore.QCoreApplication.translate

        self.actionLoad.triggered.connect(self.triggered_load)
        self.actionLoad.setShortcut(_translate("DefaultMain","Ctrl+L"))



        self.actionSave.triggered.connect(self.triggered_save)
        self.actionSave.setShortcut(_translate("DefaultMain","Ctrl+S"))

        self.actionOverview.triggered.connect(self.triggered_show_overview_menu)
        self.actionOverview.setShortcut(_translate("DefaultMain","Ctrl+O"))

        self.actionCreate.triggered.connect(self.triggered_show_create_plugin_menu)
        self.actionCreate.setShortcut(_translate("DefaultMain","Ctrl+N"))

        self.actionResetPaPI.triggered.connect(self.triggered_reset_papi)
        self.actionReloadConfig.triggered.connect(self.triggered_reload_config)

        self.actionRunMode.triggered.connect(self.toggle_run_mode)

        self.actionReload_Plugin_DB.triggered.connect(self.triggered_reload_plugin_db)

        self.actionPaPI_Wiki.triggered.connect(self.triggered_papi_wiki)

        self.actionPaPI_Doc.triggered.connect(self.triggered_papi_doc)
        self.actionPaPI_Doc.setShortcut(_translate("DefaultMain","Ctrl+H"))

        self.actionAbout.triggered.connect(self.triggered_papi_about)
        self.actionAbout_Qt.triggered.connect(self.triggered_papi_about_qt)

        self.actionToolbar.triggered.connect(self.triggered_show_toolbar)

        #self.toolBar.dragEnterEvent = self.toolbarDragEnterEvent
        #self.toolBar.dropEvent = self.toolbarDropEvent

        self.toolBar.clickedFavouritePlugin.connect(self.toolbarAddFavPlugin)
        self.toolBar.removedFavouritePlugin.connect(self.favPluginWasRemoved)

        self.set_icons()

    def addFavPlugin(self, fav_plugin):
        plugin_manager = self.gui_management.plugin_manager;

        plugin_manager.locatePlugins()

        candidates = plugin_manager.getPluginCandidates()
        all_pluginfo = {c[2].path:c[2] for c in candidates}
        loadable_pluginfo = {p.path:p for p in plugin_manager.getAllPlugins()}

        for plugin_info in all_pluginfo.values():
            if plugin_info.name == fav_plugin:

                if plugin_info.path in loadable_pluginfo.keys():
                    plugin_info = loadable_pluginfo[plugin_info.path]
                    plugin_info.loadable = True
                else:
                    plugin_info.loadable = False

                self.toolbarAddFavPlugin(plugin_info)

    def favPluginWasRemoved(self):
        self.gui_management.gui_api.do_save_xml_config_reloaded(
            pc.PAPI_USER_CFG, plToSave=[], sToSave=[], saveUserSettings=True)

    def set_icons(self):
        # -------------------------------------
        # Create Icons for buttons
        # -------------------------------------
        load_icon = get32Icon('folder')
        save_icon = get32Icon('file_save_as')
        # -------------------------------------
        # Set Icons for buttons
        # -------------------------------------
        #self.loadButton.setIconSize(QSize(32, 32))
        #self.loadButton.setIcon(load_icon)

        #self.saveButton.setIconSize(QSize(32, 32))
        #self.saveButton.setIcon(save_icon)

        # -------------------------------------
        # Create Icons for actions
        # -------------------------------------
        load_icon = get16Icon('folder')
        save_icon = get16Icon('file_save_as')
        exit_icon = get16Icon('cancel')
        overview_icon = get16Icon('tree_list')
        create_icon = get16Icon('application_add')
        reload_icon = get16Icon('arrow_rotate_clockwise')
        help_icon = get16Icon('help')
        info_icon = get16Icon('information')
        refresh_icon = get16Icon('arrow_refresh')
        delete_icon = get16Icon('delete')
        view_icon = get16Icon('reviewing_pane')

        # -------------------------------------
        # Set Icons for actions
        # -------------------------------------
        self.actionLoad.setIcon(load_icon)
        self.actionSave.setIcon(save_icon)
        self.actionExit.setIcon(exit_icon)
        self.actionOverview.setIcon(overview_icon)
        self.actionCreate.setIcon(create_icon)
        self.actionReload_Plugin_DB.setIcon(reload_icon)
        self.actionReloadConfig.setIcon(reload_icon)
        self.actionPaPI_Wiki.setIcon(help_icon)
        self.actionPaPI_Doc.setIcon(help_icon)
        self.actionAbout.setIcon(info_icon)
        self.actionAbout_Qt.setIcon(info_icon)
        self.actionAbout_PySide.setIcon(info_icon)
        self.actionResetPaPI.setIcon(delete_icon)
        self.actionRunMode.setIcon(view_icon)

        # -------------------------------------
        # Set Icons visible in menu
        # -------------------------------------
        self.actionLoad.setIconVisibleInMenu(True)
        self.actionSave.setIconVisibleInMenu(True)
        self.actionExit.setIconVisibleInMenu(True)
        self.actionOverview.setIconVisibleInMenu(True)
        self.actionCreate.setIconVisibleInMenu(True)
        self.actionReload_Plugin_DB.setIconVisibleInMenu(True)
        self.actionReloadConfig.setIconVisibleInMenu(True)
        self.actionPaPI_Wiki.setIconVisibleInMenu(True)
        self.actionPaPI_Doc.setIconVisibleInMenu(True)
        self.actionAbout.setIconVisibleInMenu(True)
        self.actionAbout_Qt.setIconVisibleInMenu(True)
        self.actionAbout_PySide.setIconVisibleInMenu(True)
        self.actionResetPaPI.setIconVisibleInMenu(True)
        self.actionRunMode.setIconVisibleInMenu(True)

    def get_gui_config(self, saveUserSettings=False):

        actTab = {}
        actTab['Active'] = str(self.TabManager.get_currently_active_tab())

        tabs = {}
        tab_dict = self.TabManager.get_tabs_by_uname()
        for tab in tab_dict:
            tabOb = tab_dict[tab]
            tabs[tab]= {}
            tabs[tab]['Background'] = tabOb.background
            tabs[tab]['Position'] = str(self.TabManager.getTabPosition_by_name(tab))

        size = {}

        size['X']= str(self.size().width())

        size['Y']= str(self.size().height())


        cfg = {}
        cfg['ActiveTab'] = actTab
        cfg['Tabs'] = tabs
        cfg['Size'] = size

        # ----------------------
        # Set favourite plugins
        # ----------------------
        if saveUserSettings:
            favourites = {}
            actions = self.toolBar.actions()
            for i in range(len(actions)):
                action = actions[i]
                if isinstance(action, PaPIFavAction):
                    favourites[action.text()] = {}
                    favourites[action.text()]['position'] = str(i)

            cfg['Favourites'] = favourites

        return cfg

    def set_gui_config(self, cfg):
        #print(cfg)
        # #################
        # # Cfgs for Tabs #
        # #################
        # if 'tabs' in cfg:
        #     tabList = {}
        #     for tab in cfg['tabs']:
        #         # Tab Name
        #         name = tab
        #
        #         # Tab details
        #         tabDetails = cfg['tabs'][tab]
        #
        #         # check for background
        #         if 'background' in tabDetails:
        #             bg = tabDetails['background']
        #             if bg != 'default':
        #                 self.TabManager.set_background_for_tab_with_name(name,bg)
        #         else:
        #             bg = None
        #
        #         # check for position
        #         if 'position' in tabDetails:
        #             pos = int(tabDetails['position'])
        #         else:
        #             if len(list(tabList.keys())) > 1:
        #                 pos = max(list(tabList.keys()))+1
        #             else:
        #                 pos = 0
        #
        #         tabList[pos] = [name, bg]
        #
        #     # sort tabs acoriding to positions
        #     keys = list(tabList.keys())
        #     keys.sort()
        #     for position in keys:
        #         name = tabList[position][0]
        #         bg = tabList[position][1]
        #         tabOb = self.TabManager.add_tab(name)
        #         self.TabManager.set_background_for_tab_with_name(name,bg)
        #
        # if 'activeTab' in cfg:
        #     if 'value' in cfg['activeTab']['active']:
        #         self.TabManager.set_tab_active_by_index(int( cfg['activeTab']['active']['value'] ))
        #
        #################
        # windows size: #
        #################
        if 'Size' in cfg:
            w = int(cfg['Size']['X'])
            h = int(cfg['Size']['Y'])
            self.resize_gui_window(w,h)

        # ------------------------
        # Restore favourite icons
        # ------------------------
        if 'Favourites' in cfg:
            sorted_positions = {}

            for plugin in cfg['Favourites']:
                sorted_positions[int(cfg['Favourites'][plugin]['position'])] = plugin

            for position in sorted(sorted_positions.keys()):
                plugin = sorted_positions[position]
                self.addFavPlugin(plugin)

        # -----------------------
        # Restore Tabs
        # -----------------------
        if 'Tabs' in cfg:
            for tabName in cfg['Tabs']:
                tab = cfg['Tabs'][tabName]
                self.TabManager.add_tab(tabName)
                if 'Background' in tab:
                    self.TabManager.set_background_for_tab_with_name(tabName, tab['Background'])

                


    def triggered_reload_plugin_db(self):
        """
        This Callback function will reload the plugin list of the plugin manager

        :return:
        """
        self.gui_management.plugin_manager.collectPlugins()

    def run(self):
        """


        :return:
        """
        # create a timer and set interval for processing events with working loop

        #QtCore.QTimer.singleShot(GUI_WOKRING_INTERVAL, lambda: self.gui_event_processing.gui_working(self.closeEvent))
        self.workingTimer = QtCore.QTimer(self)
        self.workingTimer.timeout.connect(lambda: self.gui_management.gui_event_processing.gui_working(self.closeEvent, self.workingTimer))
        self.workingTimer.start(pc.GUI_WOKRING_INTERVAL)




    def triggered_show_create_plugin_menu(self):
        """


        :return:
        """
        self.create_plugin_menu = CreatePluginMenu(self.gui_management.gui_api,
                                                   self.TabManager,
                                                   self.gui_management.plugin_manager )

        self.create_plugin_menu.show()

    def triggered_show_overview_menu(self):
        """
        Used to show the overview menu.

        :return:
        """
        self.overview_menu = OverviewPluginMenu(self.gui_management.gui_api, self.gui_management.tab_manager)
        self.overview_menu.show()

    def triggered_show_toolbar(self):
        """
        Used to hide and unhide the toolbar
        :return:
        """

        self.toolBar.setHidden(not self.toolBar.isHidden())

        self.actionToolbar.setChecked(not self.toolBar.isHidden())

    def triggered_load(self):
        """
        Used to start the 'load config' dialog.

        :return:
        """
        fileNames = ''

        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.ExistingFile)
        dialog.setNameFilter( self.tr("PaPI-Cfg (*.xml)"))
        dialog.setDirectory(pc.CONFIG_DEFAULT_DIRECTORY)
        dialog.setWindowTitle("Load Configuration")

        if dialog.exec_():
            fileNames = dialog.selectedFiles()

        if len(fileNames):
            if fileNames[0] != '':
                self.last_config = fileNames[0]
                self.load_config(fileNames[0])

    def load_config(self, file_name):
        self.gui_management.gui_api.do_load_xml(file_name)

    def triggered_save(self):
        """
        Used to start the 'save config' dialog.

        :return:
        """
        fileNames = ''

        dialog = PaPIConfigSaveDialog(self, self.gui_management.gui_api)

        dialog.fill_with()

        if dialog.exec_():
            fileNames = dialog.selectedFiles()

        plugin_list, subscription_list = dialog.get_create_lists()

        if len(fileNames):



            if fileNames[0] != '':
                if "json" in dialog.selectedNameFilter():
                    self.gui_management.gui_api.do_save_json_config_reloaded(fileNames[0], plToSave=plugin_list, sToSave=subscription_list)

                if "xml" in dialog.selectedNameFilter():
                    self.gui_management.gui_api.do_save_xml_config_reloaded(fileNames[0], plToSave=plugin_list, sToSave=subscription_list)

    def closeEvent(self, *args, **kwargs):
        """
        Handle close event.
        Saves current session as 'papi/last_active_papi.xml'
        Closes all opened windows.

        :param args:
        :param kwargs:
        :return:
        """
        try:
            self.gui_management.gui_api.do_save_xml_config('papi/last_active_papi.xml')
        except Exception as E:
            tb = traceback.format_exc()

        self.gui_management.gui_api.do_close_program()
        if self.create_plugin_menu is not None:
            self.create_plugin_menu.close()

        if self.overview_menu is not None:
            self.overview_menu.close()

        self.close()

    def add_dplugin(self, dplugin):
        """
        Callback function called by 'DPlugin added signal'
        Used to add a DPlugin SubWindow on the GUI if possible.

        :param dplugin:
        :return:
        """
        if dplugin.type == pc.PLUGIN_VIP_IDENTIFIER:

            # sub_window_ori = dplugin.plugin.get_sub_window()
            #
            # dplugin.plugin.set_window_for_internal_usage(PaPIMDISubWindow())
            # dplugin.plugin.pl_set_widget_for_internal_usage(sub_window_ori.widget())

            sub_window = dplugin.plugin._get_sub_window()

            config = dplugin.startup_config
            tab_name = config['tab']['value']
            if tab_name in self.TabManager.get_tabs_by_uname():
                area = self.TabManager.get_tabs_by_uname()[tab_name]
            else:
                self.log.printText(1,'add dplugin: no tab with tab_id of dplugin')
                area = self.TabManager.add_tab(tab_name)

            area.addSubWindow(sub_window)

            isMaximized = config['maximized']['value'] == '1'


            size_re = re.compile(r'([0-9]+)')

            pos = config['position']['value']
            window_pos = size_re.findall(pos)
            sub_window.move(int(window_pos[0]), int(window_pos[1]))

            if not isMaximized:
                sub_window.show()
            else:
                sub_window.showMaximized()

            # see http://qt-project.org/doc/qt-4.8/qt.html#WindowType-enum

            sub_window.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowMinMaxButtonsHint | Qt.WindowTitleHint )

        if self.overview_menu is not None:
            self.overview_menu.refresh_action(dplugin)

    def remove_dplugin(self, dplugin):
        """
        Callback function called by 'DPlugin removed signal'
        Used to removed a DPlugin SubWindow from the GUI if possible.

        :param dplugin:
        :return:
        """
        if dplugin.type == pc.PLUGIN_VIP_IDENTIFIER:
            config = dplugin.plugin.pl_get_current_config()
            tab_name = config['tab']['value']
            if tab_name in self.TabManager.get_tabs_by_uname():
                tabOb = self.TabManager.get_tabs_by_uname()[tab_name]
                tabOb.removeSubWindow(dplugin.plugin._get_sub_window())
                if tabOb.closeIfempty is True:
                    if len(tabOb.subWindowList()) == 0:
                        if isinstance(tabOb, TabObject):
                            self.TabManager.closeTab_by_name(tabOb.name)
                        else:
                            self.TabManager.remove_window(tabOb)


    def changed_dgui(self):
        if self.overview_menu is not None:
            self.overview_menu.refresh_action()

    def plugin_died(self, dplugin, e, msg):
        dplugin.state = pc.PLUGIN_STATE_STOPPED

        self.gui_management.gui_api.do_stopReset_plugin_uname(dplugin.uname)

        errMsg = QtGui.QMessageBox(self)
        errMsg.setFixedWidth(650)

        # layout = errMsg.layout();
        # spacer = QtGui.QSpacerItem(1000, 0, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        # layout.addItem(spacer, layout.rowCount(), 0,1, layout.columnCount())

        errMsg.setIcon(QtGui.QMessageBox.Critical)
        errMsg.setSizeGripEnabled(True)
        errMsg.setWindowTitle("Plugin: " + dplugin.uname + " // " + str(e))
        errMsg.setText("Error in plugin" + dplugin.uname + " // " + str(e))
        errMsg.setDetailedText(str(msg))
        errMsg.setWindowModality(Qt.NonModal)
        errMsg.show()

    def error_occured(self, title, msg, detailed_msg):

        errMsg = QtGui.QMessageBox(self)
        errMsg.setFixedWidth(650)

        errMsg.setWindowTitle(title)
        errMsg.setText(str(msg))
        errMsg.setDetailedText(str(detailed_msg))
        errMsg.setWindowModality(Qt.NonModal)
        errMsg.show()

    def toggle_run_mode(self):
        if self.in_run_mode is False:
            # hide toolbar
            self.toolBar.setHidden(True)
            self.actionToolbar.setChecked(False)
            # disable context menu of tabmanger
            self.TabManager.disableContextMenus()

            # lock subwindows in tabs
            for tabName in self.TabManager.tab_dict_uname:
                tabObject = self.TabManager.tab_dict_uname[tabName]

                for subWindow in tabObject.subWindowList():
                    subWindow.disableInteraction()
            self.in_run_mode = True
        else:
            # show toolbar
            self.toolBar.setHidden(False)
            self.actionToolbar.setChecked(True)
            # disable context menu of tabmanger
            self.TabManager.enableContextMenus()

            # unlock subwindows in tabs
            for tabName in self.TabManager.tab_dict_uname:
                tabObject = self.TabManager.tab_dict_uname[tabName]

                for subWindow in tabObject.subWindowList():
                    subWindow.enableInteraction()
            self.in_run_mode = False

    def toogle_lock(self):
        raise Exception("PLEASE REPORT THIS BUG!!")
        if self.in_run_mode:
            for tab_name in self.TabManager.get_tabs_by_uname():
                area = self.TabManager.get_tabs_by_uname()[tab_name]

                windowsList = area.subWindowList()

                for window in windowsList:

                    #window.setAttribute(Qt.WA_NoBackground)

                    #window.setAttribute(Qt.WA_NoSystemBackground)
                    #window.setAttribute(Qt.WA_TranslucentBackground)
                    #window.set_movable(False)
                    window.setMouseTracking(False)
                    window.setWindowFlags(~Qt.WindowMinMaxButtonsHint & (Qt.CustomizeWindowHint | Qt.WindowTitleHint))

        if not self.in_run_mode:
            for tab_name in self.TabManager.get_tabs_by_uname():
                area = self.TabManager.get_tabs_by_uname()[tab_name]

                windowsList = area.subWindowList()

                for window in windowsList:
                    #window.set_movable(True)
                    window.setMouseTracking(True)
                    window.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowMinMaxButtonsHint | Qt.WindowTitleHint )

    def keyPressEvent(self, event):
        if event.key() not in self.keysActiveList:
            self.keysActiveList.append(event.key())

        if  QtCore.Qt.Key_Escape in self.keysActiveList:
            if self.in_run_mode:
                self.toggle_run_mode()

        if QtCore.Qt.Key_D in self.keysActiveList and QtCore.Qt.Key_Control in self.keysActiveList:
            self.gui_management.tab_manager.select_next_tab()
            self.keysActiveList.remove(QtCore.Qt.Key_D)
            #self.keysActiveList.remove(QtCore.Qt.Key_Control)

        if QtCore.Qt.Key_A in self.keysActiveList and QtCore.Qt.Key_Control in self.keysActiveList:
            self.gui_management.tab_manager.select_prev_tab()
            self.keysActiveList.remove(QtCore.Qt.Key_A)
            #self.keysActiveList.remove(QtCore.Qt.Key_Control)


    def keyReleaseEvent(self, event):
        if event.key() in self.keysActiveList:
            self.keysActiveList.remove(event.key())


    def resize_gui_window(self, w, h):
        self.setGeometry(self.geometry().x(),self.geometry().y(),w,h)


    def triggered_reload_config(self):
        """
        This function is used to reset PaPI and to reload the last loaded configuration file.
        :return:
        """
        if self.last_config is not None:
            self.triggered_reset_papi()
            QtCore.QTimer.singleShot(pc.GUI_WAIT_TILL_RELOAD, lambda: self.gui_management.gui_api.do_load_xml(self.last_config))

    def triggered_reset_papi(self):
        """
        This function is called to reset PaPI. That means all subscriptions were canceled and all plugins were removed.
        :return:
        """
        h = pc.GUI_DEFAULT_HEIGHT
        w = pc.GUI_DEFAULT_WIDTH
        self.setGeometry(self.geometry().x(),self.geometry().y(),w,h)

        self.TabManager.set_all_tabs_to_close_when_empty(True)
        self.TabManager.close_all_empty_tabs()

        self.gui_management.gui_api.do_reset_papi()



    def triggered_papi_wiki(self):
        QDesktopServices.openUrl(QUrl(pc.PAPI_WIKI_URL, QUrl.TolerantMode))

    def triggered_papi_doc(self):
        QDesktopServices.openUrl(QUrl(pc.PAPI_DOC_URL, QUrl.TolerantMode))

    def triggered_papi_about(self):
        QMessageBox.about(self, pc.PAPI_ABOUT_TITLE, pc.PAPI_ABOUT_TEXT)

    def triggered_papi_about_qt(self):
        QMessageBox.aboutQt(self)

    def toolbarAddFavPlugin(self, plugin_info):

        l = len(plugin_info.name)
        path = plugin_info.path[:-l]
        path += 'box.png'
        px = QPixmap(path)

        icon = QIcon(px)

        for action in self.toolBar.actions():
            if action.text() == plugin_info.name:
                return

        plugin_action = PaPIFavAction(icon, plugin_info.name, self)
        plugin_action.triggered.connect(lambda ignore, p1=plugin_info : self.show_create_plugin_dialog(p1))

        self.toolBar.addAction(plugin_action)

        self.gui_management.gui_api.do_save_xml_config_reloaded(
            pc.PAPI_USER_CFG, plToSave=[], sToSave=[], saveUserSettings=True)

    def show_create_plugin_dialog(self, plugin_info):
        if plugin_info is not None:
            if plugin_info.loadable:
                self.plugin_create_dialog.set_plugin(plugin_info)
                self.plugin_create_dialog.show()

    def dropEvent(self, event:QDropEvent):
        source = event.source()
Example #4
0
class GUI(QMainWindow, Ui_DefaultMain):
    """
    Used to create the qt based PaPI gui.

    """
    def __init__(self,
                 core_queue=None,
                 gui_queue=None,
                 gui_id=None,
                 gui_data=None,
                 is_parent=False,
                 parent=None):
        """
        Init function

        :param core_queue: Queue used to send papi events to Core
        :param gui_queue: GUI queue which contains papi events for the gui
        :param gui_id: Unique ID for this gui
        :param gui_data: Contains all data for the current session
        :param parent: parent element
        :return:
        """
        super(GUI, self).__init__(parent)
        self.is_parent = is_parent

        self.setupUi(self)

        # Create a data structure for gui if it is missing
        # -------------------------------------------------- #
        if not isinstance(gui_data, DGui):
            self.gui_data = DGui()
        else:
            self.gui_data = gui_data

        # check if gui should be the parent process or core is the parent
        # start core if gui is parent
        # -------------------------------------------------- #
        self.core_process = None
        if is_parent:
            core_queue_ref = Queue()
            gui_queue_ref = Queue()
            gui_id_ref = 1
            self.core_process = Process(target=run_core_in_own_process,
                                        args=(gui_queue_ref, core_queue_ref,
                                              gui_id_ref))
            self.core_process.start()
        else:
            if core_queue is None:
                raise Exception('Gui started with wrong arguments')
            if gui_queue is None:
                raise Exception('Gui started with wrong arguments')
            if not isinstance(gui_id, str):
                raise Exception('Gui started with wrong arguments')

            core_queue_ref = core_queue
            gui_queue_ref = gui_queue
            gui_id_ref = gui_id

        # Create the Tab Manager and the gui management unit #
        # connect some signals of management to gui          #
        # -------------------------------------------------- #
        self.TabManager = PapiTabManger(tabWigdet=self.widgetTabs,
                                        centralWidget=self.centralwidget)

        self.gui_management = GuiManagement(core_queue_ref, gui_queue_ref,
                                            gui_id_ref, self.TabManager,
                                            self.get_gui_config,
                                            self.set_gui_config)

        self.TabManager.gui_api = self.gui_management.gui_api
        self.TabManager.dGui = self.gui_management.gui_data

        self.gui_management.gui_event_processing.added_dplugin.connect(
            self.add_dplugin)
        self.gui_management.gui_event_processing.removed_dplugin.connect(
            self.remove_dplugin)
        self.gui_management.gui_event_processing.dgui_changed.connect(
            self.changed_dgui)
        self.gui_management.gui_event_processing.plugin_died.connect(
            self.plugin_died)

        self.gui_management.gui_api.error_occured.connect(self.error_occured)

        # initialize the graphic of the gui
        # -------------------------------------------------- #
        self.gui_graphic_init()

        signal.signal(signal.SIGINT, lambda a, b: self.signal_handler(a, b))

        # List for keys that are active
        self.keysActiveList = []

    def signal_handler(self, signal, frame):
        """
        This handler will be called, when CTRL+C is used in the console
        It will react to SIGINT Signal
        As an reaction it will close the gui by first telling the core to close and then closing the gui
        :return:
        """
        self.gui_management.gui_api.do_close_program()
        sys.exit(0)

    def gui_graphic_init(self):
        self.setWindowTitle(pc.GUI_PAPI_WINDOW_TITLE)
        # set GUI size
        self.setGeometry(self.geometry().x(),
                         self.geometry().y(), pc.GUI_DEFAULT_WIDTH,
                         pc.GUI_DEFAULT_HEIGHT)

        self.count = 0

        self.log = ConsoleLog(pc.GUI_PROCESS_CONSOLE_LOG_LEVEL,
                              pc.GUI_PROCESS_CONSOLE_IDENTIFIER)

        self.log.printText(
            1, pc.GUI_START_CONSOLE_MESSAGE + ' .. Process id: ' +
            str(os.getpid()))

        self.last_config = pc.PAPI_LAST_CFG_PATH

        self.in_run_mode = False

        # -------------------------------------
        # Create placeholder
        # -------------------------------------
        self.overview_menu = None
        self.create_plugin_menu = None
        self.plugin_create_dialog = None

        # -------------------------------------
        # Create menues
        # -------------------------------------
        self.plugin_create_dialog = CreatePluginDialog(
            self.gui_management.gui_api, self.TabManager)

        # -------------------------------------
        # Create callback functions for buttons
        # -------------------------------------
        #self.loadButton.clicked.connect(self.load_triggered)
        #self.saveButton.clicked.connect(self.save_triggered)

        # -------------------------------------
        # Create actions
        # -------------------------------------
        _translate = QtCore.QCoreApplication.translate

        self.actionLoad.triggered.connect(self.triggered_load)
        self.actionLoad.setShortcut(_translate("DefaultMain", "Ctrl+L"))

        self.actionSave.triggered.connect(self.triggered_save)
        self.actionSave.setShortcut(_translate("DefaultMain", "Ctrl+S"))

        self.actionOverview.triggered.connect(
            self.triggered_show_overview_menu)
        self.actionOverview.setShortcut(_translate("DefaultMain", "Ctrl+O"))

        self.actionCreate.triggered.connect(
            self.triggered_show_create_plugin_menu)
        self.actionCreate.setShortcut(_translate("DefaultMain", "Ctrl+N"))

        self.actionResetPaPI.triggered.connect(self.triggered_reset_papi)
        self.actionReloadConfig.triggered.connect(self.triggered_reload_config)

        self.actionRunMode.triggered.connect(self.toggle_run_mode)

        self.actionReload_Plugin_DB.triggered.connect(
            self.triggered_reload_plugin_db)

        self.actionPaPI_Wiki.triggered.connect(self.triggered_papi_wiki)

        self.actionPaPI_Doc.triggered.connect(self.triggered_papi_doc)
        self.actionPaPI_Doc.setShortcut(_translate("DefaultMain", "Ctrl+H"))

        self.actionAbout.triggered.connect(self.triggered_papi_about)
        self.actionAbout_Qt.triggered.connect(self.triggered_papi_about_qt)

        self.actionToolbar.triggered.connect(self.triggered_show_toolbar)

        #self.toolBar.dragEnterEvent = self.toolbarDragEnterEvent
        #self.toolBar.dropEvent = self.toolbarDropEvent

        self.toolBar.clickedFavouritePlugin.connect(self.toolbarAddFavPlugin)
        self.toolBar.removedFavouritePlugin.connect(self.favPluginWasRemoved)

        self.set_icons()

    def addFavPlugin(self, fav_plugin):
        plugin_manager = self.gui_management.plugin_manager

        plugin_manager.locatePlugins()

        candidates = plugin_manager.getPluginCandidates()
        all_pluginfo = {c[2].path: c[2] for c in candidates}
        loadable_pluginfo = {p.path: p for p in plugin_manager.getAllPlugins()}

        for plugin_info in all_pluginfo.values():
            if plugin_info.name == fav_plugin:

                if plugin_info.path in loadable_pluginfo.keys():
                    plugin_info = loadable_pluginfo[plugin_info.path]
                    plugin_info.loadable = True
                else:
                    plugin_info.loadable = False

                self.toolbarAddFavPlugin(plugin_info)

    def favPluginWasRemoved(self):
        self.gui_management.gui_api.do_save_xml_config_reloaded(
            pc.PAPI_USER_CFG, plToSave=[], sToSave=[], saveUserSettings=True)

    def set_icons(self):
        # -------------------------------------
        # Create Icons for buttons
        # -------------------------------------
        load_icon = get32Icon('folder')
        save_icon = get32Icon('file_save_as')
        # -------------------------------------
        # Set Icons for buttons
        # -------------------------------------
        #self.loadButton.setIconSize(QSize(32, 32))
        #self.loadButton.setIcon(load_icon)

        #self.saveButton.setIconSize(QSize(32, 32))
        #self.saveButton.setIcon(save_icon)

        # -------------------------------------
        # Create Icons for actions
        # -------------------------------------
        load_icon = get16Icon('folder')
        save_icon = get16Icon('file_save_as')
        exit_icon = get16Icon('cancel')
        overview_icon = get16Icon('tree_list')
        create_icon = get16Icon('application_add')
        reload_icon = get16Icon('arrow_rotate_clockwise')
        help_icon = get16Icon('help')
        info_icon = get16Icon('information')
        refresh_icon = get16Icon('arrow_refresh')
        delete_icon = get16Icon('delete')
        view_icon = get16Icon('reviewing_pane')

        # -------------------------------------
        # Set Icons for actions
        # -------------------------------------
        self.actionLoad.setIcon(load_icon)
        self.actionSave.setIcon(save_icon)
        self.actionExit.setIcon(exit_icon)
        self.actionOverview.setIcon(overview_icon)
        self.actionCreate.setIcon(create_icon)
        self.actionReload_Plugin_DB.setIcon(reload_icon)
        self.actionReloadConfig.setIcon(reload_icon)
        self.actionPaPI_Wiki.setIcon(help_icon)
        self.actionPaPI_Doc.setIcon(help_icon)
        self.actionAbout.setIcon(info_icon)
        self.actionAbout_Qt.setIcon(info_icon)
        self.actionAbout_PySide.setIcon(info_icon)
        self.actionResetPaPI.setIcon(delete_icon)
        self.actionRunMode.setIcon(view_icon)

        # -------------------------------------
        # Set Icons visible in menu
        # -------------------------------------
        self.actionLoad.setIconVisibleInMenu(True)
        self.actionSave.setIconVisibleInMenu(True)
        self.actionExit.setIconVisibleInMenu(True)
        self.actionOverview.setIconVisibleInMenu(True)
        self.actionCreate.setIconVisibleInMenu(True)
        self.actionReload_Plugin_DB.setIconVisibleInMenu(True)
        self.actionReloadConfig.setIconVisibleInMenu(True)
        self.actionPaPI_Wiki.setIconVisibleInMenu(True)
        self.actionPaPI_Doc.setIconVisibleInMenu(True)
        self.actionAbout.setIconVisibleInMenu(True)
        self.actionAbout_Qt.setIconVisibleInMenu(True)
        self.actionAbout_PySide.setIconVisibleInMenu(True)
        self.actionResetPaPI.setIconVisibleInMenu(True)
        self.actionRunMode.setIconVisibleInMenu(True)

    def get_gui_config(self, saveUserSettings=False):

        actTab = {}
        actTab['Active'] = str(self.TabManager.get_currently_active_tab())

        tabs = {}
        tab_dict = self.TabManager.get_tabs_by_uname()
        for tab in tab_dict:
            tabOb = tab_dict[tab]
            tabs[tab] = {}
            tabs[tab]['Background'] = tabOb.background
            tabs[tab]['Position'] = str(
                self.TabManager.getTabPosition_by_name(tab))

        size = {}

        size['X'] = str(self.size().width())

        size['Y'] = str(self.size().height())

        cfg = {}
        cfg['ActiveTab'] = actTab
        cfg['Tabs'] = tabs
        cfg['Size'] = size

        # ----------------------
        # Set favourite plugins
        # ----------------------
        if saveUserSettings:
            favourites = {}
            actions = self.toolBar.actions()
            for i in range(len(actions)):
                action = actions[i]
                if isinstance(action, PaPIFavAction):
                    favourites[action.text()] = {}
                    favourites[action.text()]['position'] = str(i)

            cfg['Favourites'] = favourites

        return cfg

    def set_gui_config(self, cfg):
        #print(cfg)
        # #################
        # # Cfgs for Tabs #
        # #################
        # if 'tabs' in cfg:
        #     tabList = {}
        #     for tab in cfg['tabs']:
        #         # Tab Name
        #         name = tab
        #
        #         # Tab details
        #         tabDetails = cfg['tabs'][tab]
        #
        #         # check for background
        #         if 'background' in tabDetails:
        #             bg = tabDetails['background']
        #             if bg != 'default':
        #                 self.TabManager.set_background_for_tab_with_name(name,bg)
        #         else:
        #             bg = None
        #
        #         # check for position
        #         if 'position' in tabDetails:
        #             pos = int(tabDetails['position'])
        #         else:
        #             if len(list(tabList.keys())) > 1:
        #                 pos = max(list(tabList.keys()))+1
        #             else:
        #                 pos = 0
        #
        #         tabList[pos] = [name, bg]
        #
        #     # sort tabs acoriding to positions
        #     keys = list(tabList.keys())
        #     keys.sort()
        #     for position in keys:
        #         name = tabList[position][0]
        #         bg = tabList[position][1]
        #         tabOb = self.TabManager.add_tab(name)
        #         self.TabManager.set_background_for_tab_with_name(name,bg)
        #
        # if 'activeTab' in cfg:
        #     if 'value' in cfg['activeTab']['active']:
        #         self.TabManager.set_tab_active_by_index(int( cfg['activeTab']['active']['value'] ))
        #
        #################
        # windows size: #
        #################
        if 'Size' in cfg:
            w = int(cfg['Size']['X'])
            h = int(cfg['Size']['Y'])
            self.resize_gui_window(w, h)

        # ------------------------
        # Restore favourite icons
        # ------------------------
        if 'Favourites' in cfg:
            sorted_positions = {}

            for plugin in cfg['Favourites']:
                sorted_positions[int(
                    cfg['Favourites'][plugin]['position'])] = plugin

            for position in sorted(sorted_positions.keys()):
                plugin = sorted_positions[position]
                self.addFavPlugin(plugin)

        # -----------------------
        # Restore Tabs
        # -----------------------
        if 'Tabs' in cfg:
            for tabName in cfg['Tabs']:
                tab = cfg['Tabs'][tabName]
                self.TabManager.add_tab(tabName)
                if 'Background' in tab:
                    self.TabManager.set_background_for_tab_with_name(
                        tabName, tab['Background'])

    def triggered_reload_plugin_db(self):
        """
        This Callback function will reload the plugin list of the plugin manager

        :return:
        """
        self.gui_management.plugin_manager.collectPlugins()

    def run(self):
        """


        :return:
        """
        # create a timer and set interval for processing events with working loop

        #QtCore.QTimer.singleShot(GUI_WOKRING_INTERVAL, lambda: self.gui_event_processing.gui_working(self.closeEvent))
        self.workingTimer = QtCore.QTimer(self)
        self.workingTimer.timeout.connect(
            lambda: self.gui_management.gui_event_processing.gui_working(
                self.closeEvent, self.workingTimer))
        self.workingTimer.start(pc.GUI_WOKRING_INTERVAL)

    def triggered_show_create_plugin_menu(self):
        """


        :return:
        """
        self.create_plugin_menu = CreatePluginMenu(
            self.gui_management.gui_api, self.TabManager,
            self.gui_management.plugin_manager)

        self.create_plugin_menu.show()

    def triggered_show_overview_menu(self):
        """
        Used to show the overview menu.

        :return:
        """
        self.overview_menu = OverviewPluginMenu(
            self.gui_management.gui_api, self.gui_management.tab_manager)
        self.overview_menu.show()

    def triggered_show_toolbar(self):
        """
        Used to hide and unhide the toolbar
        :return:
        """

        self.toolBar.setHidden(not self.toolBar.isHidden())

        self.actionToolbar.setChecked(not self.toolBar.isHidden())

    def triggered_load(self):
        """
        Used to start the 'load config' dialog.

        :return:
        """
        fileNames = ''

        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.ExistingFile)
        dialog.setNameFilter(self.tr("PaPI-Cfg (*.xml)"))
        dialog.setDirectory(pc.CONFIG_DEFAULT_DIRECTORY)
        dialog.setWindowTitle("Load Configuration")

        if dialog.exec_():
            fileNames = dialog.selectedFiles()

        if len(fileNames):
            if fileNames[0] != '':
                self.last_config = fileNames[0]
                self.load_config(fileNames[0])

    def load_config(self, file_name):
        self.gui_management.gui_api.do_load_xml(file_name)

    def triggered_save(self):
        """
        Used to start the 'save config' dialog.

        :return:
        """
        fileNames = ''

        dialog = PaPIConfigSaveDialog(self, self.gui_management.gui_api)

        dialog.fill_with()

        if dialog.exec_():
            fileNames = dialog.selectedFiles()

        plugin_list, subscription_list = dialog.get_create_lists()

        if len(fileNames):

            if fileNames[0] != '':
                if "json" in dialog.selectedNameFilter():
                    self.gui_management.gui_api.do_save_json_config_reloaded(
                        fileNames[0],
                        plToSave=plugin_list,
                        sToSave=subscription_list)

                if "xml" in dialog.selectedNameFilter():
                    self.gui_management.gui_api.do_save_xml_config_reloaded(
                        fileNames[0],
                        plToSave=plugin_list,
                        sToSave=subscription_list)

    def closeEvent(self, *args, **kwargs):
        """
        Handle close event.
        Saves current session as 'papi/last_active_papi.xml'
        Closes all opened windows.

        :param args:
        :param kwargs:
        :return:
        """
        try:
            self.gui_management.gui_api.do_save_xml_config(
                'papi/last_active_papi.xml')
        except Exception as E:
            tb = traceback.format_exc()

        self.gui_management.gui_api.do_close_program()
        if self.create_plugin_menu is not None:
            self.create_plugin_menu.close()

        if self.overview_menu is not None:
            self.overview_menu.close()

        self.close()

    def add_dplugin(self, dplugin):
        """
        Callback function called by 'DPlugin added signal'
        Used to add a DPlugin SubWindow on the GUI if possible.

        :param dplugin:
        :return:
        """
        if dplugin.type == pc.PLUGIN_VIP_IDENTIFIER:

            # sub_window_ori = dplugin.plugin.get_sub_window()
            #
            # dplugin.plugin.set_window_for_internal_usage(PaPIMDISubWindow())
            # dplugin.plugin.pl_set_widget_for_internal_usage(sub_window_ori.widget())

            sub_window = dplugin.plugin._get_sub_window()

            config = dplugin.startup_config
            tab_name = config['tab']['value']
            if tab_name in self.TabManager.get_tabs_by_uname():
                area = self.TabManager.get_tabs_by_uname()[tab_name]
            else:
                self.log.printText(
                    1, 'add dplugin: no tab with tab_id of dplugin')
                area = self.TabManager.add_tab(tab_name)

            area.addSubWindow(sub_window)

            isMaximized = config['maximized']['value'] == '1'

            size_re = re.compile(r'([0-9]+)')

            pos = config['position']['value']
            window_pos = size_re.findall(pos)
            sub_window.move(int(window_pos[0]), int(window_pos[1]))

            if not isMaximized:
                sub_window.show()
            else:
                sub_window.showMaximized()

            # see http://qt-project.org/doc/qt-4.8/qt.html#WindowType-enum

            sub_window.setWindowFlags(Qt.CustomizeWindowHint
                                      | Qt.WindowMinMaxButtonsHint
                                      | Qt.WindowTitleHint)

        if self.overview_menu is not None:
            self.overview_menu.refresh_action(dplugin)

    def remove_dplugin(self, dplugin):
        """
        Callback function called by 'DPlugin removed signal'
        Used to removed a DPlugin SubWindow from the GUI if possible.

        :param dplugin:
        :return:
        """
        if dplugin.type == pc.PLUGIN_VIP_IDENTIFIER:
            config = dplugin.plugin.pl_get_current_config()
            tab_name = config['tab']['value']
            if tab_name in self.TabManager.get_tabs_by_uname():
                tabOb = self.TabManager.get_tabs_by_uname()[tab_name]
                tabOb.removeSubWindow(dplugin.plugin._get_sub_window())
                if tabOb.closeIfempty is True:
                    if len(tabOb.subWindowList()) == 0:
                        if isinstance(tabOb, TabObject):
                            self.TabManager.closeTab_by_name(tabOb.name)
                        else:
                            self.TabManager.remove_window(tabOb)

    def changed_dgui(self):
        if self.overview_menu is not None:
            self.overview_menu.refresh_action()

    def plugin_died(self, dplugin, e, msg):
        dplugin.state = pc.PLUGIN_STATE_STOPPED

        self.gui_management.gui_api.do_stopReset_plugin_uname(dplugin.uname)

        errMsg = QtGui.QMessageBox(self)
        errMsg.setFixedWidth(650)

        # layout = errMsg.layout();
        # spacer = QtGui.QSpacerItem(1000, 0, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        # layout.addItem(spacer, layout.rowCount(), 0,1, layout.columnCount())

        errMsg.setIcon(QtGui.QMessageBox.Critical)
        errMsg.setSizeGripEnabled(True)
        errMsg.setWindowTitle("Plugin: " + dplugin.uname + " // " + str(e))
        errMsg.setText("Error in plugin" + dplugin.uname + " // " + str(e))
        errMsg.setDetailedText(str(msg))
        errMsg.setWindowModality(Qt.NonModal)
        errMsg.show()

    def error_occured(self, title, msg, detailed_msg):

        errMsg = QtGui.QMessageBox(self)
        errMsg.setFixedWidth(650)

        errMsg.setWindowTitle(title)
        errMsg.setText(str(msg))
        errMsg.setDetailedText(str(detailed_msg))
        errMsg.setWindowModality(Qt.NonModal)
        errMsg.show()

    def toggle_run_mode(self):
        if self.in_run_mode is False:
            # hide toolbar
            self.toolBar.setHidden(True)
            self.actionToolbar.setChecked(False)
            # disable context menu of tabmanger
            self.TabManager.disableContextMenus()

            # lock subwindows in tabs
            for tabName in self.TabManager.tab_dict_uname:
                tabObject = self.TabManager.tab_dict_uname[tabName]

                for subWindow in tabObject.subWindowList():
                    subWindow.disableInteraction()
            self.in_run_mode = True
        else:
            # show toolbar
            self.toolBar.setHidden(False)
            self.actionToolbar.setChecked(True)
            # disable context menu of tabmanger
            self.TabManager.enableContextMenus()

            # unlock subwindows in tabs
            for tabName in self.TabManager.tab_dict_uname:
                tabObject = self.TabManager.tab_dict_uname[tabName]

                for subWindow in tabObject.subWindowList():
                    subWindow.enableInteraction()
            self.in_run_mode = False

    def toogle_lock(self):
        raise Exception("PLEASE REPORT THIS BUG!!")
        if self.in_run_mode:
            for tab_name in self.TabManager.get_tabs_by_uname():
                area = self.TabManager.get_tabs_by_uname()[tab_name]

                windowsList = area.subWindowList()

                for window in windowsList:

                    #window.setAttribute(Qt.WA_NoBackground)

                    #window.setAttribute(Qt.WA_NoSystemBackground)
                    #window.setAttribute(Qt.WA_TranslucentBackground)
                    #window.set_movable(False)
                    window.setMouseTracking(False)
                    window.setWindowFlags(~Qt.WindowMinMaxButtonsHint
                                          & (Qt.CustomizeWindowHint
                                             | Qt.WindowTitleHint))

        if not self.in_run_mode:
            for tab_name in self.TabManager.get_tabs_by_uname():
                area = self.TabManager.get_tabs_by_uname()[tab_name]

                windowsList = area.subWindowList()

                for window in windowsList:
                    #window.set_movable(True)
                    window.setMouseTracking(True)
                    window.setWindowFlags(Qt.CustomizeWindowHint
                                          | Qt.WindowMinMaxButtonsHint
                                          | Qt.WindowTitleHint)

    def keyPressEvent(self, event):
        if event.key() not in self.keysActiveList:
            self.keysActiveList.append(event.key())

        if QtCore.Qt.Key_Escape in self.keysActiveList:
            if self.in_run_mode:
                self.toggle_run_mode()

        if QtCore.Qt.Key_D in self.keysActiveList and QtCore.Qt.Key_Control in self.keysActiveList:
            self.gui_management.tab_manager.select_next_tab()
            self.keysActiveList.remove(QtCore.Qt.Key_D)
            #self.keysActiveList.remove(QtCore.Qt.Key_Control)

        if QtCore.Qt.Key_A in self.keysActiveList and QtCore.Qt.Key_Control in self.keysActiveList:
            self.gui_management.tab_manager.select_prev_tab()
            self.keysActiveList.remove(QtCore.Qt.Key_A)
            #self.keysActiveList.remove(QtCore.Qt.Key_Control)

    def keyReleaseEvent(self, event):
        if event.key() in self.keysActiveList:
            self.keysActiveList.remove(event.key())

    def resize_gui_window(self, w, h):
        self.setGeometry(self.geometry().x(), self.geometry().y(), w, h)

    def triggered_reload_config(self):
        """
        This function is used to reset PaPI and to reload the last loaded configuration file.
        :return:
        """
        if self.last_config is not None:
            self.triggered_reset_papi()
            QtCore.QTimer.singleShot(
                pc.GUI_WAIT_TILL_RELOAD, lambda: self.gui_management.gui_api.
                do_load_xml(self.last_config))

    def triggered_reset_papi(self):
        """
        This function is called to reset PaPI. That means all subscriptions were canceled and all plugins were removed.
        :return:
        """
        h = pc.GUI_DEFAULT_HEIGHT
        w = pc.GUI_DEFAULT_WIDTH
        self.setGeometry(self.geometry().x(), self.geometry().y(), w, h)

        self.TabManager.set_all_tabs_to_close_when_empty(True)
        self.TabManager.close_all_empty_tabs()

        self.gui_management.gui_api.do_reset_papi()

    def triggered_papi_wiki(self):
        QDesktopServices.openUrl(QUrl(pc.PAPI_WIKI_URL, QUrl.TolerantMode))

    def triggered_papi_doc(self):
        QDesktopServices.openUrl(QUrl(pc.PAPI_DOC_URL, QUrl.TolerantMode))

    def triggered_papi_about(self):
        QMessageBox.about(self, pc.PAPI_ABOUT_TITLE, pc.PAPI_ABOUT_TEXT)

    def triggered_papi_about_qt(self):
        QMessageBox.aboutQt(self)

    def toolbarAddFavPlugin(self, plugin_info):

        l = len(plugin_info.name)
        path = plugin_info.path[:-l]
        path += 'box.png'
        px = QPixmap(path)

        icon = QIcon(px)

        for action in self.toolBar.actions():
            if action.text() == plugin_info.name:
                return

        plugin_action = PaPIFavAction(icon, plugin_info.name, self)
        plugin_action.triggered.connect(
            lambda ignore, p1=plugin_info: self.show_create_plugin_dialog(p1))

        self.toolBar.addAction(plugin_action)

        self.gui_management.gui_api.do_save_xml_config_reloaded(
            pc.PAPI_USER_CFG, plToSave=[], sToSave=[], saveUserSettings=True)

    def show_create_plugin_dialog(self, plugin_info):
        if plugin_info is not None:
            if plugin_info.loadable:
                self.plugin_create_dialog.set_plugin(plugin_info)
                self.plugin_create_dialog.show()

    def dropEvent(self, event: QDropEvent):
        source = event.source()