Ejemplo n.º 1
0
    def setup_possible_locations_tree(self):
        """
        Creates the possible_locations_tree with all worlds, areas and nodes.
        """
        self.possible_locations_tree.itemDoubleClicked.connect(
            self._on_tree_node_double_clicked)

        # TODO: Dark World names
        for world in self.game_description.world_list.worlds:
            world_item = QTreeWidgetItem(self.possible_locations_tree)
            world_item.setText(0, world.name)
            world_item.setExpanded(True)
            self._asset_id_to_item[world.world_asset_id] = world_item

            for area in world.areas:
                area_item = QTreeWidgetItem(world_item)
                area_item.area = area
                area_item.setText(0, area.name)
                area_item.setHidden(True)
                self._asset_id_to_item[area.area_asset_id] = area_item

                for node in area.nodes:
                    node_item = QTreeWidgetItem(area_item)
                    if isinstance(node, TranslatorGateNode):
                        node_item.setText(
                            0, "{} ({})".format(node.name, node.gate))
                    else:
                        node_item.setText(0, node.name)
                    node_item.node = node
                    if node.is_resource_node:
                        node_item.setFlags(node_item.flags()
                                           & ~Qt.ItemIsUserCheckable)
                    self._node_to_item[node] = node_item
Ejemplo n.º 2
0
        def build_menu_by_recursive(root: QTreeWidgetItem, menu_dict: dict):
            for key in menu_dict:
                item = QTreeWidgetItem()

                item_font = QFont()
                item_font.setPointSize(
                    self.config.getint('master', 'master_item_font_size'))
                try:
                    text = str(menu_dict[key]['text'])
                    item.setText(0, text)
                    item.setFont(0, item_font)
                except KeyError:
                    pass
                try:
                    descript = str(menu_dict[key]['descript'])
                    item.setToolTip(0, descript)
                except KeyError:
                    pass
                try:
                    scl = str(menu_dict[key]['scl'])
                    item.setText(2, scl)
                except KeyError:
                    pass
                try:
                    children = menu_dict[key]['children']
                    build_menu_by_recursive(item, children)
                except KeyError:
                    pass
                try:
                    expanded = menu_dict[key]['expanded']
                    item.setExpanded(expanded)
                except KeyError:
                    pass

                root.addChild(item)
Ejemplo n.º 3
0
 def _create(self):
     struct = self.dm.getStructure(self.isInverse)
     for ws in struct:
         gparent = QTreeWidgetItem(self)
         gparent.setText(0, ws)
         for key in struct[ws]:
             parent = QTreeWidgetItem(gparent)
             parent.setText(0, key)
             parent.setFlags(parent.flags() | Qt.ItemIsTristate
                             | Qt.ItemIsUserCheckable)
             if (self.inputList is not None and key == self.inputList[1]
                     and ws == self.inputList[0]):
                 channelsChecked = True
                 gparent.setExpanded(True)
                 self.curChecked = parent
                 parent.setSelected(True)
             else:
                 channelsChecked = False
             for k in struct[ws][key]:
                 child = QTreeWidgetItem(parent)
                 child.setFlags(child.flags())
                 child.setText(0, k)
                 if channelsChecked:
                     child.setCheckState(0, Qt.Checked)
                 else:
                     child.setCheckState(0, Qt.Unchecked)
class CopyDBDialog(QDialog, Ui_Dialog):
    def __init__(self, db_url, parent=None):
        QDialog.__init__(self, parent)
        Ui_Dialog.setupUi(self, self)
        self.db_url = db_url
        self.selectButton.clicked.connect(self.slot_accept)
        self.cancelButton.clicked.connect(self.slot_reject)
        self.success = False
        self.collection = None
        t = threading.Thread(target=self.fill_tree_widget)
        t.start()

    def slot_accept(self):
        col = self.get_collection()
        if col is not None:
            self.collection, c_name, c_type = col
            self.success = True
        self.close()

    def slot_reject(self):
        self.close()

    def fill_tree_widget(self, parent=None):
        if parent is None:
            self.collectionTreeWidget.clear()
            self.rootItem = QTreeWidgetItem(self.collectionTreeWidget,
                                            ["root", "root"])
            self.rootItem.setExpanded(True)
            # root collection has id 0
            parent_id = 0
            parent_item = self.rootItem
            self.rootItem.setData(0, Qt.UserRole, parent_id)
        else:
            parent_id = parent[1]
            parent_item = parent[0]

        collection_list = get_collections_by_parent_id_from_remote_db(
            self.db_url, parent_id)
        for col in collection_list:
            colItem = QTreeWidgetItem(parent_item, [col[1], col[2]])
            colItem.setData(0, Qt.UserRole, col[0])
            self.fill_tree_widget((colItem, col[0]))

    def get_collection(self):
        colItem = self.collectionTreeWidget.currentItem()
        if colItem is None:
            return
        return int(colItem.data(0, Qt.UserRole)), str(colItem.text(0)), str(
            colItem.text(1))
class SelectTransitionDialog(QDialog, Ui_Dialog):
    def __init__(self, graph_data, parent=None):
        QDialog.__init__(self, parent)
        Ui_Dialog.setupUi(self, self)
        self.graph_data = graph_data
        self.selectButton.clicked.connect(self.slot_accept)
        self.cancelButton.clicked.connect(self.slot_reject)
        self.success = False
        self.transition_name = ""
        self.transition_entry = None
        self.fill_tree_widget()

    def slot_accept(self):
        colItem = self.collectionTreeWidget.currentItem()
        if colItem is None or colItem.parent() is None:
            return
        model_name = str(colItem.text(0))
        action_name = str(colItem.parent().text(0))
        model_id = int(colItem.data(0, Qt.UserRole))
        self.transition_name = action_name + ":" + model_name
        self.transition_entry = {
            "action_name": action_name,
            "model_name": model_name,
            "model_id": model_id
        }
        self.success = True
        self.close()

    def slot_reject(self):
        self.close()

    def fill_tree_widget(self):
        self.collectionTreeWidget.clear()
        self.rootItem = QTreeWidgetItem(self.collectionTreeWidget,
                                        ["root", "root"])
        self.rootItem.setExpanded(True)
        # root collection has id 0
        self.rootItem.setData(0, Qt.UserRole, 0)
        for action in self.graph_data["nodes"]:
            actionItem = QTreeWidgetItem(self.rootItem, [action, "action"])
            actionItem.setData(0, Qt.UserRole, action)
            for mp_id in self.graph_data["nodes"][action]:
                model_name = self.graph_data["nodes"][action][mp_id]["name"]
                mpItem = QTreeWidgetItem(actionItem, [model_name, "primitive"])
                mpItem.setData(0, Qt.UserRole, int(mp_id))
Ejemplo n.º 6
0
    def __init__(self, ui_file):
        super(Form, self).__init__()
        ui_file = QFile(ui_file)
        ui_file.open(QFile.ReadOnly)
        loader = QUiLoader()
        self.window = loader.load(ui_file)
        self.window.setFixedSize(self.window.width(), self.window.height());
        ui_file.close()

        self.tree = self.window.findChild(QTreeWidget, 'treeMenu')
        #        self.tree.itemSelectionChanged.connect(self.itemSelection)
        self.tree.currentItemChanged.connect(self.itemSelection)
        self.tree.itemClicked.connect(self.itemSelection)
        menulist = ["Cadastro de Pessoa"]
        itemlist = ["Inserir", "Atualizar", "Excluir", "Listar"]
        for str in menulist:
            parent = QTreeWidgetItem(self.tree)
            parent.setText(0, str)
            for opcao in itemlist:
                child = QTreeWidgetItem(parent)
                child.setText(0, opcao)
            parent.setExpanded(1)
        self.window.show()
        return
Ejemplo n.º 7
0
    def build_toplevel_menu(self, surpac_scl_cfg: str):
        # Tree递归构建
        def build_menu_by_recursive(root: QTreeWidgetItem, menu_dict: dict):
            for key in menu_dict:
                item = QTreeWidgetItem()

                item_font = QFont()
                item_font.setPointSize(
                    self.config.getint('master', 'master_item_font_size'))
                try:
                    text = str(menu_dict[key]['text'])
                    item.setText(0, text)
                    item.setFont(0, item_font)
                except KeyError:
                    pass
                try:
                    descript = str(menu_dict[key]['descript'])
                    item.setToolTip(0, descript)
                except KeyError:
                    pass
                try:
                    scl = str(menu_dict[key]['scl'])
                    item.setText(2, scl)
                except KeyError:
                    pass
                try:
                    children = menu_dict[key]['children']
                    build_menu_by_recursive(item, children)
                except KeyError:
                    pass
                try:
                    expanded = menu_dict[key]['expanded']
                    item.setExpanded(expanded)
                except KeyError:
                    pass

                root.addChild(item)

        surpac_scl_encoding = self.config.get('master', 'surpac_scl_encoding')
        menus = []
        with open(file=surpac_scl_cfg, encoding=surpac_scl_encoding) as _f:
            menu_dict = yaml.load(_f, yaml.loader.FullLoader)
            for key in menu_dict:
                menu_toplevel_item = QTreeWidgetItem()
                menu_toplevel_item_font = QFont()
                menu_toplevel_item_font.setPointSize(
                    self.config.getint('master', 'master_root_font_size'))

                try:
                    text = str(menu_dict[key]['text'])
                    menu_toplevel_item.setText(0, text)
                    menu_toplevel_item.setFont(0, menu_toplevel_item_font)
                except KeyError:
                    pass

                try:
                    descript = str(menu_dict[key]['descript'])
                    menu_toplevel_item.setToolTip(0, descript)
                except KeyError:
                    pass

                try:
                    scl = str(menu_dict[key]['scl'])
                    menu_toplevel_item.setText(2, scl)
                except KeyError:
                    pass

                try:
                    expanded = menu_dict[key]['expanded']
                    menu_toplevel_item.setExpanded(expanded)
                except KeyError:
                    pass

                try:
                    children = menu_dict[key]['children']
                    build_menu_by_recursive(menu_toplevel_item, children)
                except KeyError:
                    pass

            menus.append(menu_toplevel_item)

        return menus
Ejemplo n.º 8
0
class EditCollectionDialog(QDialog, Ui_Dialog):
    def __init__(self,
                 collection_id,
                 parent_name,
                 parent_id,
                 default_name="",
                 col_type="",
                 owner=0,
                 parent=None):
        QDialog.__init__(self, parent)
        Ui_Dialog.setupUi(self, self)
        self.acceptButton.clicked.connect(self.slot_accept)
        self.rejectButton.clicked.connect(self.slot_reject)
        self.parent_name = parent_name
        self.collection_id = collection_id
        #self.parentLabel.setText("Parent: "+parent_name)
        self.parent_id = parent_id
        self.db_url = DB_URL
        self.success = False
        self.name = default_name
        self.nameLineEdit.setText(default_name)
        self.col_type = col_type
        self.typeLineEdit.setText(col_type)
        self.ownerLineEdit.setText(str(owner))
        t = threading.Thread(target=self.fill_tree_widget)
        t.start()

    def fill_tree_widget(self, parent=None):
        if parent is None:
            self.collectionTreeWidget.clear()
            self.rootItem = QTreeWidgetItem(self.collectionTreeWidget,
                                            ["root", "root"])
            self.rootItem.setExpanded(True)
            # root collection has id 0
            parent_id = 0
            parent_item = self.rootItem
            self.rootItem.setData(0, Qt.UserRole, parent_id)
        else:
            parent_id = parent[1]
            parent_item = parent[0]

        collection_list = get_collections_by_parent_id_from_remote_db(
            self.db_url, parent_id)
        for col in collection_list:
            if col[0] == self.collection_id:
                self.select_tree_node(parent_item)
                continue
            colItem = QTreeWidgetItem(parent_item, [col[1], col[2]])
            colItem.setData(0, Qt.UserRole, col[0])
            self.fill_tree_widget((colItem, col[0]))

    def select_tree_node(self, node):
        node.setSelected(True)
        while node is not None:
            node.setExpanded(True)
            node = node.parent()

    def get_collection(self):
        colItem = self.collectionTreeWidget.currentItem()
        if colItem is None:
            return
        return int(colItem.data(0, Qt.UserRole)), str(colItem.text(0)), str(
            colItem.text(1))

    def slot_accept(self):
        col = self.get_collection()
        if col is not None:
            self.parent_id, self.parent_name, c_type = col
            self.success = True
        self.name = str(self.nameLineEdit.text())
        self.col_type = str(self.typeLineEdit.text())
        self.owner = int(self.ownerLineEdit.text())
        self.success = True
        self.close()

    def slot_reject(self):
        self.close()
Ejemplo n.º 9
0
class GraphDefinitionDialog(QDialog, Ui_Dialog):
    def __init__(self, db_url, skeleton, graph_data=None, name="",parent=None):
        QDialog.__init__(self, parent)
        Ui_Dialog.setupUi(self, self)
        self.skeleton = skeleton
        self.db_url = db_url
        self.selectButton.clicked.connect(self.slot_accept)
        self.cancelButton.clicked.connect(self.slot_reject)
        self.success = False
        t = threading.Thread(target=self.fill_tree_widget)
        t.start()

        self.graphRootItem = QTreeWidgetItem(self.graphTreeWidget, ["root", "root"])
        self.graphRootItem.setExpanded(True)
        self.data = graph_data
        if self.data is not None:
            if "start_node" not in self.data:
                self.data["start_node"] = ""
            self.init_graph_view()
        else:
            self.data = dict()
            self.data["nodes"] = dict()
            self.data["start_node"] = ""
        self.name = name
        self.nameLineEdit.setText(name)

        self.collectionTreeWidget.itemClicked.connect(self._fill_model_list_from_db)
        self.modelListWidget.itemClicked.connect(self.update_selected_model)
        self.graphTreeWidget.itemClicked.connect(self.update_model_info)


        self.addModelButton.clicked.connect(self.slot_add_primitive)
        self.replaceModelButton.clicked.connect(self.slot_replace_primitive)
        self.addActionButton.clicked.connect(self.slot_add_action)
        self.removeGraphItemButton.clicked.connect(self.slot_remove_graph_item)
        self.setToStartNodeButton.clicked.connect(self.slot_set_to_start_node)
    
        self.addTransitionButton.clicked.connect(self.slot_add_transition)
        self.removeTransitionButton.clicked.connect(self.slot_remove_transition)
        self.fill_node_type_combobox()
        self.nodeTypeComboBox.currentIndexChanged.connect(self.update_node_type)
        self._fill_model_list_from_db()
    
    def init_graph_view(self):
        print("init graph view")
        start_node = str(self.data["start_node"])
        self.startNodeLabel.setText(start_node)
        for action_name in self.data["nodes"]:
            actionItem = QTreeWidgetItem(self.graphRootItem, [action_name, "action"])
            for mp_id in self.data["nodes"][action_name]:
                mp_name = self.data["nodes"][action_name][mp_id]["name"]
                mpItem = QTreeWidgetItem(actionItem, [mp_name, "primitive"])
                mpItem.setData(0, Qt.UserRole, int(mp_id))

    def slot_accept(self):
        self.name = str(self.nameLineEdit.text())
        self.success = self.name != ""
        self.close()

    def slot_reject(self):
        self.close()

    def slot_add_primitive(self):
        selected_action = self.graphTreeWidget.currentItem()
        selected_primitive = self.modelListWidget.currentItem()
        if selected_action is not None and selected_primitive is not None:
            action_name = str(selected_action.text(0))
            type_str = str(selected_action.text(1))
            if type_str == "action":
                mp_id = int(selected_primitive.data(Qt.UserRole))
                mp_name = str(selected_primitive.text())
                mp_key = str(mp_id)
                if mp_key not in self.data["nodes"][action_name]:
                    mpItem = QTreeWidgetItem(selected_action, [mp_name, "primitive"])
                    mpItem.setData(0, Qt.UserRole, mp_id)
                    mp_dict = dict()
                    mp_dict["transitions"] = dict()
                    mp_dict["type"] = "standard"
                    mp_dict["name"] = mp_name
                    self.data["nodes"][action_name][mp_key] = mp_dict
                else:
                    print(mp_name, "already part of action", action_name)
        
    def slot_replace_primitive(self):
        selected_graph_node = self.graphTreeWidget.currentItem()
        selected_primitive = self.modelListWidget.currentItem()
        if selected_graph_node is not None and selected_primitive is not None:
            type_str = str(selected_graph_node.text(1))
            if type_str == "primitive":
                action_node = selected_graph_node.parent()
                action_name = str(action_node.text(0))
                if action_name in self.data["nodes"]:
                    old_mp_id = int(selected_graph_node.data(0, Qt.UserRole))
                    old_mp_name = str(selected_graph_node.text(0))
                    old_key = str(old_mp_id)

                    new_mp_id = int(selected_primitive.data(Qt.UserRole))
                    new_mp_name = str(selected_primitive.text())
                    new_key = str(new_mp_id)
                    if old_key in self.data["nodes"][action_name]:
                        old_transitions = self.data["nodes"][action_name][old_key]["transitions"]
                        old_type = self.data["nodes"][action_name][old_key]["type"]
                        del self.data["nodes"][action_name][old_key]
                        selected_graph_node.setText(0, new_mp_name)
                        selected_graph_node.setData(0, Qt.UserRole, new_mp_id)

                        mp_dict = dict()
                        mp_dict["transitions"] = old_transitions
                        mp_dict["type"] = old_type
                        mp_dict["name"] = new_mp_name
                        self.data["nodes"][action_name][new_key] = mp_dict
                        self.replace_transitions(action_name, old_mp_name, old_mp_id, new_mp_name, new_mp_id)
                        self.update_model_info()
                        print("replaced", old_mp_id, "with", new_mp_id)
                else:
                    print(old_mp_name, "not part of action", action_name)

    def replace_transitions(self, action_name, old_model_name, old_model_id, new_model_name, new_model_id):
        old_key = action_name+":"+old_model_name
        new_key = action_name+":"+new_model_name
        new_entry = dict()
        new_entry["model_name"] = new_model_name
        new_entry["model_id"] = new_model_id
        for a in self.data["nodes"]:
            for mp in self.data["nodes"][a]:
                if old_key in self.data["nodes"][a][mp]["transitions"]:
                    del self.data["nodes"][a][mp]["transitions"][old_key]
                    self.data["nodes"][a][mp]["transitions"][new_key] = copy(new_entry)


    def slot_remove_graph_item(self):
        item = self.graphTreeWidget.currentItem()
        if item is not None: #and item != self.graphRootItem
            parent_item = item.parent()
            item_name = str(item.text(0))
            parent_name = str(parent_item.text(0))
            if parent_name in self.data["nodes"]:
                mp_id = str(item.data(0, Qt.UserRole))
                if mp_id in self.data["nodes"][parent_name]:
                    del self.data["nodes"][parent_name][mp_id]
                
            elif item_name in self.data["nodes"]:
                del self.data["nodes"][item_name]
            parent_item.removeChild(item)

    def slot_set_to_start_node(self):
        item = self.graphTreeWidget.currentItem()
        if item is not None: #and item != self.graphRootItem
            parent_item = item.parent()
            if parent_item is not None:
                item_name = str(item.text(0))
                parent_name = str(parent_item.text(0))
                start_node = [parent_name, item_name]
                start_node_str = str(start_node)
                self.data["start_node"] = [parent_name, item_name]
                self.startNodeLabel.setText(start_node_str)
        


    def slot_add_action(self):
        dialog = EnterNameDialog()
        dialog.exec_()
        if dialog.success:
            action_name = dialog.name
            if action_name not in self.data["nodes"]:
                actionItem = QTreeWidgetItem(self.graphRootItem, [action_name, "action"])
                self.data["nodes"][action_name] = dict()

    def slot_add_transition(self):
        item = self.graphTreeWidget.currentItem()
        if item is not None:
            parent_item = item.parent()
            item_name = str(item.text(0))
            type_name = str(item.text(1))
            parent_name = str(parent_item.text(0))
            if type_name == "primitive":
                mp_id = str(item.data(0, Qt.UserRole))
                if mp_id in self.data["nodes"][parent_name]:
                    dialog = SelectTransitionDialog(self.data)
                    dialog.exec_()
                    if dialog.success and dialog.transition_entry is not None:
                        
                        action_name = str(dialog.transition_entry["action_name"])
                        model_name = str(dialog.transition_entry["model_name"])
                        name = action_name+":"+model_name
                        self.data["nodes"][parent_name][mp_id]["transitions"][name] = dialog.transition_entry
                        self.update_model_info()
        

    def slot_remove_transition(self):
        selected_transition = self.transitionListWidget.currentItem()
        if selected_transition is not None:
            self.transitionListWidget.takeItem(self.transitionListWidget.row(selected_transition))
            transiton_name = str(selected_transition.text())
            selected_item = self.graphTreeWidget.currentItem()
            action_name =  str(selected_item.parent().text(0))
            #mp_name = str(selected_item.text(0))
            mp_id = str(selected_item.data(0, Qt.UserRole))
            del self.data["nodes"][action_name][mp_id]["transitions"][transiton_name]
            self.update_model_info()

    def fill_tree_widget(self, parent=None):
        if parent is None:
            self.collectionTreeWidget.clear()
            self.rootItem = QTreeWidgetItem(self.collectionTreeWidget, ["root", "root"])
            self.rootItem.setExpanded(True)
            # root collection has id 0
            parent_id = 0
            parent_item = self.rootItem
            self.rootItem.setData(0, Qt.UserRole, parent_id)
        else:
            parent_id = parent[1]
            parent_item = parent[0]

        collection_list = get_collections_by_parent_id_from_remote_db(self.db_url, parent_id)
        for col in collection_list:
            colItem = QTreeWidgetItem(parent_item, [col[1], col[2]])
            colItem.setData(0, Qt.UserRole, col[0])
            self.fill_tree_widget((colItem, col[0]))

    def get_collection(self):
        colItem = self.collectionTreeWidget.currentItem()
        if colItem is None:
            return
        return int(colItem.data(0, Qt.UserRole)),  str(colItem.text(0)), str(colItem.text(1))


    def _fill_model_list_from_db(self, idx=None):
        self.modelListWidget.clear()
        col = self.get_collection()
        if col is None:
            return
        c_id, c_name, c_type = col
        model_list = get_model_list_from_remote_db(self.db_url, c_id, self.skeleton)
        print("model list", model_list)
        if model_list is None:
            return
        for node_id, name in model_list:
            item = QListWidgetItem()
            item.setText(name)
            item.setData(Qt.UserRole, node_id)
            self.modelListWidget.addItem(item)

        self.update_selected_model()
        
    def update_selected_model(self):
        selected_action = self.graphTreeWidget.currentItem()
        selected_primitive = self.modelListWidget.currentItem()
        if selected_action is not None and selected_primitive is not None:
            self.selectedModelLabel.setText(selected_primitive.text())
        else:
            self.selectedModelLabel.setText("None")

    def update_model_info(self, idx=None):
        self.transitionListWidget.clear()
        self.nodeTypeComboBox.setCurrentIndex(0)
        selected_item = self.graphTreeWidget.currentItem()
        if selected_item is None:
            return
        item_type = str(selected_item.text(1))
        if item_type != "primitive":
            return
        item_name = str(selected_item.text(0))
        mp_id = str(selected_item.data(0, Qt.UserRole))
        action_name = str(selected_item.parent().text(0))
        if action_name not in self.data["nodes"]:
            return
        if mp_id not in self.data["nodes"][action_name]:
            print("mp id  not in nodes", mp_id)
            return
        for transiton_key in self.data["nodes"][action_name][mp_id]["transitions"]:
            item = QListWidgetItem()
            item.setText(transiton_key)
            self.transitionListWidget.addItem(item)
        
        node_type = self.data["nodes"][action_name][mp_id]["type"]
        index = self.nodeTypeComboBox.findText(node_type, Qt.MatchFixedString)
        if index >= 0:
            self.nodeTypeComboBox.setCurrentIndex(index)
        print("node_type", node_type, index, mp_id)



    def fill_node_type_combobox(self):
        self.nodeTypeComboBox.clear()
        self.nodeTypeComboBox.addItem("", 0)
        self.nodeTypeComboBox.addItem("standard", 1)
        self.nodeTypeComboBox.addItem("start", 2)
        self.nodeTypeComboBox.addItem("end", 3)
        self.nodeTypeComboBox.addItem("single", 4)
        self.nodeTypeComboBox.addItem("idle", 5)

    def update_node_type(self):
        selected_item = self.graphTreeWidget.currentItem()
        if selected_item is None:
            return
        item_type = str(selected_item.text(1))
        if item_type != "primitive":
            return
        item_name = str(selected_item.text(0))
        mp_id = str(selected_item.data(0, Qt.UserRole))
        action_name = str(selected_item.parent().text(0))
        if action_name not in self.data["nodes"]:
            return
        if mp_id not in self.data["nodes"][action_name]:
            return
        node_type = str(self.nodeTypeComboBox.currentText())
        if node_type != "":
            self.data["nodes"][action_name][mp_id]["type"] = node_type
            print("set node type", item_name, node_type)
Ejemplo n.º 10
0
    def loadBacktestTree(self):
        options = self.config.get("options", {})
        underlyings = options.get("underlyings", [])

        for i in range(1):
            item = self.backtest_tree.topLevelItem(i)
            item.setExpanded(True)
            for j in range(item.childCount()):
                child_item = item.child(j)
                child_item.setExpanded(True)
                whatsthis = child_item.whatsThis(0)
                if whatsthis == "option":
                    for underlying in underlyings:
                        current_item = child_item
                        node = QTreeWidgetItem(current_item)
                        node.setText(0, underlying["name"])
                        node.setCheckState(0, Qt.Unchecked)
                        node.setWhatsThis(0, "option_underlying")
                        node.setExpanded(True)

                        data = underlying.get("id",
                                              {}).get("data", pd.DataFrame())
                        if not data.empty:
                            id_dict = underlying.get("id", {})
                            name = id_dict["list"][id_dict["value"]]
                            childSubWindow = {
                                "title": "%s的当日合约",
                                "type": "option_contract_table",
                                "table_name": "%date%",
                                "where": "",
                                "select": id,
                                "hidden_columns": [],
                                "index_column": [],
                                "childSubWindow": {},
                            }
                            hidden_columns = [
                                'total_turnover', 'limit_up', 'limit_down',
                                'settlement', 'prev_settlement',
                                'discount_rate', 'acc_net_value',
                                'unit_net_value', 'date', 'open_interest',
                                'iopv', 'num_trades'
                            ]

                            GridView(self.parent,
                                     name,
                                     data,
                                     id=name,
                                     hidden_columns=hidden_columns,
                                     index_column='date',
                                     childSubWindow=childSubWindow,
                                     type="option_underlying")
                        current_item = node

                        groups = underlying.get("groups", [])
                        for group in groups:
                            node = QTreeWidgetItem(current_item)
                            node.setText(0, group["name"])
                            node.setCheckState(0, Qt.Unchecked)
                            node.setIcon(0, QtGui.QIcon("../icon/group.png"))
                            node.setWhatsThis(0, "option_group")
                            node.setExpanded(True)
                            current_item = node
                            contracts = group.get("contracts")
                            for contract in contracts:
                                node = QTreeWidgetItem(current_item)
                                node.setText(0, contract["name"])
                                node.setCheckState(0, Qt.Unchecked)
                                node.setWhatsThis(0, "option_contract")
                                node.setExpanded(True)
                                current_item = node
class RetargetDBDialog(QDialog, Ui_Dialog):
    def __init__(self, db_url, parent=None):
        QDialog.__init__(self, parent)
        Ui_Dialog.setupUi(self, self)
        self.db_url = db_url
        self.selectButton.clicked.connect(self.slot_accept)
        self.cancelButton.clicked.connect(self.slot_reject)
        self.success = False
        self.scale_factor = 1.0
        self.place_on_ground = False
        self.fill_combo_box_with_skeletons()
        t = threading.Thread(target=self.fill_tree_widget)
        t.start()
        self.src_model = None
        self.target_model = None
        self.collection = None

    def fill_combo_box_with_skeletons(self):
        skeleton_list = get_skeletons_from_remote_db(self.db_url)
        for idx, skel, owner in skeleton_list:
            self.sourceModelComboBox.addItem(skel, idx)
            self.targetModelComboBox.addItem(skel, idx)

    def slot_accept(self):
        self.scale_factor = float(self.scaleLineEdit.text())
        self.src_model = str(self.sourceModelComboBox.currentText())
        self.target_model = str(self.targetModelComboBox.currentText())
        self.place_on_ground = self.placeOnGroundRadioButton.isChecked()
            
        col = self.get_collection()
        if col is not None:
            self.collection, c_name, c_type = col
            self.success = True
        self.close()

    def slot_reject(self):
        self.close()#

    def fill_tree_widget(self, parent=None):
        if parent is None:
            self.collectionTreeWidget.clear()
            self.rootItem = QTreeWidgetItem(self.collectionTreeWidget, ["root", "root"])
            self.rootItem.setExpanded(True)
            # root collection has id 0
            parent_id = 0
            parent_item = self.rootItem
            self.rootItem.setData(0, Qt.UserRole, parent_id)
        else:
            parent_id = parent[1]
            parent_item = parent[0]

        collection_list = get_collections_by_parent_id_from_remote_db(self.db_url, parent_id)
        for col in collection_list:
            colItem = QTreeWidgetItem(parent_item, [col[1], col[2]])
            colItem.setData(0, Qt.UserRole, col[0])
            self.fill_tree_widget((colItem, col[0]))


    def get_collection(self):
        colItem = self.collectionTreeWidget.currentItem()
        if colItem is None:
            return
        return int(colItem.data(0, Qt.UserRole)),  str(colItem.text(0)), str(colItem.text(1))
class SonetPCPManagerQt(QDialog, sonet_pcp_manager_ui.Ui_sonet_pcp_manager):
    """
    Window in charge of managing the available PCP trajectories within the app,
    and also generates new ones, if desired.

    The matlab data is stored in .mat files, in matrix format.
    The app needs pcp data in table format. The tables are stored in .pkl files.
    """
    def __init__(self, *args, p_main_window=None, p_mat_eng=None):
        super(SonetPCPManagerQt, self).__init__(*args)
        self.setupUi(self)
        self.setModal(True)
        self.show()

        # Reference to the main window.
        self._p_main_window = p_main_window

        # Reference to matlab engine.
        self._p_matlab_engine = p_mat_eng

        # Some widgets settings.
        self.sonet_read_pcp_qtw.setHeaderLabels([
            'Selected .mat files', 'Total trajectories', 'Departure Dates',
            'TOFs'
        ])
        self.matrix_tw_outgoing_root_item = QTreeWidgetItem(
            self.sonet_read_pcp_qtw, ['Earth-Mars', '', '', ''])
        self.matrix_tw_incoming_root_item = QTreeWidgetItem(
            self.sonet_read_pcp_qtw, ['Mars-Earth', '', '', ''])
        self.resize_matrix_tw_columns()

        self.sonet_working_pcp_qtw.setHeaderLabels(
            ['Selected .pkl files', 'Rows', 'Columns'])
        self.table_tw_outgoing_root_item = QTreeWidgetItem(
            self.sonet_working_pcp_qtw, ['Earth-Mars', '', ''])
        self.table_tw_incoming_root_item = QTreeWidgetItem(
            self.sonet_working_pcp_qtw, ['Mars-Earth', '', ''])
        self.resize_table_tw_columns()

        # Status bar,for messages to the user.
        self.status_bar = QStatusBar()
        self.status_bar.setBaseSize(580, 22)
        self.status_bar.setSizeGripEnabled(False)
        self.status_bar_HLayout.addWidget(self.status_bar)

        # Other members.
        self._pcp_mat_file_incoming = None
        self._pcp_mat_file_outgoing = None
        self._pcp_table_file_incoming = None
        self._pcp_table_file_outgoing = None

        # Signals and slots connect.
        self.sonet_read_pcp_outgoing_trajectories_matrix_qpb.clicked.connect(
            self.clicked_read_pcp_matrix_file_outgoing)
        self.sonet_read_pcp_incoming_trajectories_matrix_qpb.clicked.connect(
            self.clicked_read_pcp_matrix_file_incoming)
        self.sonet_dvt_limit_qcb.stateChanged.connect(
            self.clicked_dvt_limit_checkbox)
        self.sonet_convert_pcp_2_table_format_qpb.clicked.connect(
            self.clicked_convert_pcp_2_table_format)
        self.sonet_read_pcp_outgoing_trajectories_table_qpb.clicked.connect(
            self.clicked_read_pcp_table_file_outgoing)
        self.sonet_read_pcp_incoming_trajectories_table_qpb.clicked.connect(
            self.clicked_read_pcp_table_file_incoming)
        self.matlab_pcp_generator_pb.clicked.connect(
            self.clicked_matlab_pcp_generator)
        self.btn_OK = self.sonet_ok_cancel_qpb_group.button(
            QDialogButtonBox.Ok)
        self.btn_OK.clicked.connect(self.clicked_ok)
        self.btn_OK.clicked.connect(self.accept)

        self.btn_cancel = self.sonet_ok_cancel_qpb_group.button(
            QDialogButtonBox.Cancel)
        self.btn_cancel.clicked.connect(self.clicked_cancel)
        self.btn_cancel.clicked.connect(self.reject)

        # If there's a currently working pcp in the database, display it to the user.
        self.read_database_pcp()

        # sonet_log(SonetLogType.INFO, 'class_tal.method_tal')
        # self.status_bar.showMessage('tal.', SONET_MSG_TIMEOUT)

    def read_database_pcp(self):
        """
        If there's a currently working pcp in the database, display it to the user.

        """
        working_pcp_paths = database.get_working_pcp_paths()
        pkl_file_outgoing_path = working_pcp_paths[0]
        pkl_file_incoming_path = working_pcp_paths[1]
        # Fill the pkl files path line edit widgets.
        self.sonet__outgoing_trajectories_table_line_edit.setText(
            pkl_file_outgoing_path)
        self.sonet__incoming_trajectories_table_line_edit.setText(
            pkl_file_incoming_path)

        # Set the members pkl files & update the table tree view.
        if pkl_file_outgoing_path:
            self._pcp_table_file_outgoing = database.get_pcp_table(
                TripType.OUTGOING)
            self.update_table_tree_view(pkl_file_outgoing_path,
                                        p_trip='Earth-Mars')
        if pkl_file_incoming_path:
            self._pcp_table_file_incoming = database.get_pcp_table(
                TripType.INCOMING)
            self.update_table_tree_view(pkl_file_incoming_path,
                                        p_trip='Mars-Earth')

    def clicked_ok(self):
        """
        Sets the current working pcp files (if any) & close the window.
        If we have changed the outgoing or incoming pkl files, all the currently set trajectories are going to be reset.
        If the s/c had any filter, it remains unchanged.
        """

        pkl_file_path_outgoing = self.sonet__outgoing_trajectories_table_line_edit.text(
        )
        pkl_file_path_incoming = self.sonet__incoming_trajectories_table_line_edit.text(
        )
        has_changed_outgoing = database.set_working_pcp(
            TripType.OUTGOING, pkl_file_path_outgoing)
        has_changed_incoming = database.set_working_pcp(
            TripType.INCOMING, pkl_file_path_incoming)

        # Reset the trajectories for ALL the s/c if necessary, AND inform to the user.
        if has_changed_outgoing or has_changed_incoming:
            reset_sc_filters_and_trajectories(
                p_filters_and_trajectories='Trajectories')
            self._p_main_window.statusbar.showMessage(
                'Database has changed. Selected trajectories reset for ALL s/c',
                SONET_MSG_TIMEOUT * 3)
            self._exit_status = 'clicked_ok_and_changed'
        else:
            self._exit_status = 'clicked_ok'

    def clicked_cancel(self):
        """
        Abort all the operations & close the window.
        """
        self._exit_status = 'clicked_cancel'

    def clicked_convert_pcp_2_table_format(self):
        """
        Converts matrix to tabular pcp data. .mat -> .pkl.
        - Reads all the current available .mat files.
        - Converts them to tabular format (pandas dataframes).
            - Also does some filtering (i.e. max dvt).
        - Saves the tables to pickle .pkl files.
        """
        # self.status_bar.showMessage('SonetPCPManagerQt.clicked_convert_pcp_2_table_format."Not implemented."',
        #                             SONET_MSG_TIMEOUT)

        # Check if user has limited the dvt value.
        dvt_widget = self.sonet_dvt_limit_qdoublespinbox
        if dvt_widget.isEnabled():
            dvt_limit_value = dvt_widget.value()
        else:
            dvt_limit_value = None

        # Convert mat obj to dataframe obj.
        result = []
        for mat_file in [
                self._pcp_mat_file_outgoing, self._pcp_mat_file_incoming
        ]:
            if mat_file is None:
                result.append(None)
            else:
                result.append(
                    self.convert_mat_2_dataframe(mat_file, dvt_limit_value))

        # Save the dataframes to pickle files.
        for df in result:
            df: pd.DataFrame
            if df is not None:
                file_path = df.attrs['file_name']
                file_name = file_path.split('/')[-2]
                self.status_bar.showMessage('Writing' + file_name + 'pkl file',
                                            2 * SONET_MSG_TIMEOUT)
                df.to_pickle(file_path)

        self.status_bar.showMessage('Pickle files written',
                                    2 * SONET_MSG_TIMEOUT)

        # Remove mat files and reset associated widgets.
        self.reset_matrix_widgets()

    def clicked_dvt_limit_checkbox(self):
        """
        Activate/deactivate the dvt limit line edit widget, depending of the check box state.
        """
        self.sonet_dvt_limit_qdoublespinbox.setEnabled(
            self.sonet_dvt_limit_qcb.isChecked())

    def clicked_matlab_pcp_generator(self):
        self._p_matlab_engine.PCPGenerator(nargout=0)

    def clicked_read_pcp_matrix_file_incoming(self):
        """
        Opens a select file dialog, the user has to select a valid matlab .mat file containing the pcp data.
        """
        file_path, filter_ = QFileDialog.getOpenFileName(
            parent=self,
            caption='Read PCP file (.mat)',
            dir=SONET_PCP_DATA_DIR,
            filter='*.mat')
        if file_path:
            self.sonet__incoming_trajectories_matrix_line_edit.setText(
                file_path)
        else:  # The user canceled the open file window.
            return
        self._pcp_mat_file_incoming = loadmat(file_path)
        self.status_bar.showMessage('PCP incoming .mat file read',
                                    SONET_MSG_TIMEOUT)

        file_name = file_path.split('/')[-2]
        my_mat_file_dep_dates = self._pcp_mat_file_incoming[
            'departure_dates'].shape[1]
        my_mat_file_tofs = self._pcp_mat_file_incoming['tofs'].shape[1]
        my_mat_file_total_trajectories = my_mat_file_dep_dates * my_mat_file_tofs
        self.fill_matrix_QTreeWidget('Mars-Earth', file_name,
                                     str(my_mat_file_total_trajectories),
                                     str(my_mat_file_dep_dates),
                                     str(my_mat_file_dep_dates))

    def clicked_read_pcp_matrix_file_outgoing(self):
        """
        Opens a select file dialog, the user has to select a valid matlab .mat file containing the pcp data.
        """

        # Read the .mat file.
        file_path, filter_ = QFileDialog.getOpenFileName(
            parent=self,
            caption='Read PCP file (.mat)',
            dir=SONET_PCP_DATA_DIR,
            filter='*.mat')
        if file_path:
            self.sonet__outgoing_trajectories_matrix_line_edit.setText(
                file_path)
        else:  # The user canceled the open file window.
            return

        self._pcp_mat_file_outgoing = loadmat(file_path)
        self.status_bar.showMessage('PCP outgoing .mat file read',
                                    SONET_MSG_TIMEOUT)

        file_name = file_path.split('/')[-2]
        my_mat_file_dep_dates = self._pcp_mat_file_outgoing[
            'departure_dates'].shape[1]
        my_mat_file_tofs = self._pcp_mat_file_outgoing['tofs'].shape[1]
        my_mat_file_total_trajectories = my_mat_file_dep_dates * my_mat_file_tofs
        self.fill_matrix_QTreeWidget('Earth-Mars', file_name,
                                     str(my_mat_file_total_trajectories),
                                     str(my_mat_file_dep_dates),
                                     str(my_mat_file_dep_dates))

    def clicked_read_pcp_table_file_incoming(self):
        """
        Opens a select file dialog, the user has to select a valid pickle .pkl file containing the pcp data.
        """
        file_path, filter_ = QFileDialog.getOpenFileName(
            parent=self,
            caption='Read PCP file (.pkl)',
            dir=SONET_PCP_DATA_DIR,
            filter='*.pkl')
        if file_path:
            self.sonet__incoming_trajectories_table_line_edit.setText(
                file_path)
        else:  # The user canceled the open file window.
            return

        # Read the Python .pkl file.
        self._pcp_table_file_incoming = pd.read_pickle(file_path)
        self.status_bar.showMessage('PCP incoming .pkl file read',
                                    SONET_MSG_TIMEOUT)

        # Update the bottom tree view.
        self.update_table_tree_view(file_path, p_trip='Mars-Earth')

    def update_table_tree_view(self, a_file_path, p_trip=''):
        a_file_name = a_file_path.split('/')[-2]

        if p_trip == 'Earth-Mars':
            my_pkl_file_rows = self._pcp_table_file_outgoing.shape[0]
            my_pkl_file_cols = self._pcp_table_file_outgoing.shape[1]
            self.fill_table_QTreeWidget('Earth-Mars', a_file_name,
                                        str(my_pkl_file_rows),
                                        str(my_pkl_file_cols))
        else:
            my_pkl_file_rows = self._pcp_table_file_incoming.shape[0]
            my_pkl_file_cols = self._pcp_table_file_incoming.shape[1]
            self.fill_table_QTreeWidget('Mars-Earth', a_file_name,
                                        str(my_pkl_file_rows),
                                        str(my_pkl_file_cols))

    def clicked_read_pcp_table_file_outgoing(self):
        """
        Opens a select file dialog, the user has to select a valid pickle .pkl file containing the pcp data.
        """
        # Read the file name.
        file_path, filter_ = QFileDialog.getOpenFileName(
            parent=self,
            caption='Read PCP file (.pkl)',
            dir=SONET_PCP_DATA_DIR,
            filter='*.pkl')
        if file_path:
            self.sonet__outgoing_trajectories_table_line_edit.setText(
                file_path)
        else:  # The user canceled the open file window.
            return

        # Read the Python .pkl file.
        self._pcp_table_file_outgoing = pd.read_pickle(file_path)
        self.status_bar.showMessage('PCP outgoing .pkl file read',
                                    SONET_MSG_TIMEOUT)

        # Update the bottom tree view.
        self.update_table_tree_view(file_path, p_trip='Earth-Mars')

    def reset_matrix_widgets(self):
        self._pcp_mat_file_outgoing = None
        self._pcp_mat_file_incoming = None
        self.sonet_dvt_limit_qcb.setChecked(False)
        self.sonet__outgoing_trajectories_matrix_line_edit.clear()
        self.sonet__incoming_trajectories_matrix_line_edit.clear()
        self.matrix_tw_outgoing_root_item.takeChildren()
        self.matrix_tw_incoming_root_item.takeChildren()

    @staticmethod
    def convert_mat_2_dataframe(a_my_mat_file,
                                a_dvt_limit=None) -> pd.DataFrame:
        """
        Converts the input mat file to tabular data, in the form of pandas dataframe obj.
        :param a_my_mat_file: input mat file.
        :param a_dvt_limit: the max dvt allowed for the output dataframe.
        """
        # Initialize the data structures.
        table_rows = a_my_mat_file['departure_dates'].shape[
            1]  # Table rows is N.
        table_size = table_rows**2  # Table size is N^2.

        rows = [i for i in range(table_size)]
        cols = ['DepDates', 'tof', 'c3d', 'c3a', 'dvd', 'dva', 'dvt', 'theta']
        data = np.zeros((table_size, len(cols)), dtype=np.double)

        # Do the conversion.
        get_value = SonetPCPManagerQt._fill_the_table_data
        row = 0
        for i in range(0, table_rows):  # For each departure date.
            # print(i)
            for j in range(0, table_rows):  # For each tof.
                # First, check max dvt, if greater than the cut-off value, discard this table row.
                dvt = get_value(a_my_mat_file, 'dvt', i, j)
                if dvt > a_dvt_limit:
                    continue

                # Independent vars are (1,table_rows) ndarrays.
                data[row, 0] = get_value(a_my_mat_file, 'departure_dates', 0,
                                         i)
                data[row, 1] = get_value(a_my_mat_file, 'tofs', 0, j)

                # Dependent vars are (table_rows,table_rows) ndarrays.
                data[row, 2] = get_value(a_my_mat_file, 'c3d', i, j)
                data[row, 3] = get_value(a_my_mat_file, 'c3a', i, j)
                data[row, 4] = get_value(a_my_mat_file, 'dvd', i, j)
                data[row, 5] = get_value(a_my_mat_file, 'dva', i, j)
                data[row, 6] = dvt
                data[row, 7] = get_value(a_my_mat_file, 'theta', i, j)

                row = row + 1

        # If the user has set a dvt limit, the returned dataframe my have less rows than the original expected.
        if a_dvt_limit:
            unfilled_rows = len(rows) - row
            df = pd.DataFrame(data[:-unfilled_rows, :],
                              columns=cols,
                              index=[i for i in range(row)])
        else:
            df = pd.DataFrame(data, columns=cols, index=rows)

        # Add 'ArrivDates' column and perform some conversions and columns reordering.
        df = SonetPCPManagerQt.post_process(df)

        # Add attributes to the dataframe.
        df.attrs['file_name'] = str(a_my_mat_file['fname'][0]) + '.pkl'
        df.attrs['limit_dvt'] = a_dvt_limit
        df.attrs['memory_usage'] = int(df.memory_usage().sum() / 1e6)
        df.attrs['m_departure_dates'] = a_my_mat_file[
            'departure_dates'].tolist()[0]
        df.attrs['m_tofs'] = a_my_mat_file['tofs'].tolist()[0]
        return df

    @staticmethod
    def _fill_the_table_data(a_my_mat_file, var='', row=0, col=0):
        return a_my_mat_file[var][row, col]

    def fill_matrix_QTreeWidget(self,
                                a_file_type='',
                                a_file_name='',
                                a_total_trajectories='0',
                                a_total_dep_dates='0',
                                a_total_tofs='0',
                                p_clean_qtw_before_cleaning=False):
        if p_clean_qtw_before_cleaning:
            self.sonet_read_pcp_qtw.clear()

        # root_node = self.sonet_read_pcp_qtw.invisibleRootItem()

        if a_file_type == 'Earth-Mars':
            self.matrix_tw_outgoing_root_item.takeChildren()
            the_new_item = QTreeWidgetItem(self.matrix_tw_outgoing_root_item, [
                a_file_name, a_total_trajectories, a_total_dep_dates,
                a_total_tofs
            ])
        else:
            self.matrix_tw_incoming_root_item.takeChildren()
            the_new_item = QTreeWidgetItem(self.matrix_tw_incoming_root_item, [
                a_file_name, a_total_trajectories, a_total_dep_dates,
                a_total_tofs
            ])
        self.matrix_tw_outgoing_root_item.setExpanded(True)
        self.matrix_tw_incoming_root_item.setExpanded(True)
        self.resize_matrix_tw_columns()

    def fill_table_QTreeWidget(self,
                               a_file_type='',
                               a_file_name='',
                               a_total_rows='0',
                               a_total_cols='0',
                               p_clean_qtw_before_cleaning=False):
        if p_clean_qtw_before_cleaning:
            self.sonet_working_pcp_qtw.clear()

        if a_file_type == 'Earth-Mars':
            self.table_tw_outgoing_root_item.takeChildren()
            the_new_item = QTreeWidgetItem(
                self.table_tw_outgoing_root_item,
                [a_file_name, a_total_rows, a_total_cols])
        else:
            self.table_tw_incoming_root_item.takeChildren()
            the_new_item = QTreeWidgetItem(
                self.table_tw_incoming_root_item,
                [a_file_name, a_total_rows, a_total_cols])
        self.table_tw_outgoing_root_item.setExpanded(True)
        self.table_tw_incoming_root_item.setExpanded(True)
        self.resize_table_tw_columns()

    def resize_matrix_tw_columns(self):
        self.sonet_read_pcp_qtw.resizeColumnToContents(0)
        self.sonet_read_pcp_qtw.resizeColumnToContents(1)
        self.sonet_read_pcp_qtw.resizeColumnToContents(2)
        self.sonet_read_pcp_qtw.resizeColumnToContents(3)

    def resize_table_tw_columns(self):
        self.sonet_working_pcp_qtw.resizeColumnToContents(0)
        self.sonet_working_pcp_qtw.resizeColumnToContents(1)
        self.sonet_working_pcp_qtw.resizeColumnToContents(2)

    @staticmethod
    def post_process(a_df: pd.DataFrame):
        """
        Given a input dataframe:
            - Creates a new column called 'ArrivDates', which is a lineal combination of 'DepDates' and 'tof'.
            - Converts 'DepDates' and 'ArrivDates' from JD2000 to JD, as QDate objects work with absolute dates.
            - Converts 'theta' from radians to sexagesimal degrees.
            - Reorder columns in a more convenient way.
        :param a_df: a Pandas DataFrame.
        """

        # Create 'ArrivDates' column.
        a_df['ArrivDates'] = a_df.DepDates + a_df.tof

        # Convert dates JD2000 to JD.
        JD2000 = 2451545.0  # Julian Day 2000, extracted from AstroLib matlab code.
        a_df['DepDates'] = (a_df.DepDates + JD2000)
        a_df['ArrivDates'] = (a_df.ArrivDates + JD2000)

        # Convert theta rad to º.
        a_df.theta = a_df.theta * 180 / np.pi

        # Reorder columns.
        reordered_cols = [
            'DepDates', 'ArrivDates', 'tof', 'theta', 'dvt', 'dvd', 'dva',
            'c3d', 'c3a'
        ]
        return a_df.reindex(columns=reordered_cols)
class UploadMotionDialog(QDialog, Ui_Dialog):
    def __init__(self, controller_list, parent=None):
        QDialog.__init__(self, parent)
        self.controller_list = controller_list
        Ui_Dialog.setupUi(self, self)
        self.selectButton.clicked.connect(self.slot_accept)
        self.cancelButton.clicked.connect(self.slot_reject)
        self.db_url = constants.DB_URL
        self.session = SessionManager.session
        self.urlLineEdit.setText(self.db_url)
        self.motion_table = "motion_clips"
        self.action_table = "motion_primitives"
        self.action_table = "actions"
        self.action = "grasp"
        self.success = False
        self.fill_combo_box_with_skeletons()
        t = threading.Thread(target=self.fill_tree_widget)
        t.start()
        self.urlLineEdit.textChanged.connect(self.set_url)

    def set_url(self, text):
        print("set url", text)
        self.db_url = str(text)

    def fill_tree_widget(self, parent=None):
        if parent is None:
            self.collectionTreeWidget.clear()
            self.rootItem = QTreeWidgetItem(self.collectionTreeWidget,
                                            ["root", "root"])
            self.rootItem.setExpanded(True)
            # root collection has id 0
            parent_id = 0
            parent_item = self.rootItem
            self.rootItem.setData(0, Qt.UserRole, parent_id)
        else:
            parent_id = parent[1]
            parent_item = parent[0]

        collection_list = get_collections_by_parent_id_from_remote_db(
            self.db_url, parent_id)
        for col in collection_list:
            colItem = QTreeWidgetItem(parent_item, [col[1], col[2]])
            colItem.setData(0, Qt.UserRole, col[0])
            self.fill_tree_widget((colItem, col[0]))

    def get_collection(self):
        colItem = self.collectionTreeWidget.currentItem()
        if colItem is None:
            return
        return int(colItem.data(0, Qt.UserRole)), str(colItem.text(0)), str(
            colItem.text(1))

    def fill_combo_box_with_skeletons(self):
        self.skeletonModelComboBox.clear()
        skeleton_list = get_skeletons_from_remote_db(self.db_url)
        for idx, s in enumerate(skeleton_list):
            self.skeletonModelComboBox.addItem(s[1], idx)

    def slot_accept(self):
        skeleton_name = str(self.skeletonModelComboBox.currentText())
        col = self.get_collection()
        if col is not None:
            c_id, c_name, c_type = col
            self.success = True

            is_processed = bool(self.isProcessedCheckBox.isChecked())
            for c in self.controller_list:
                name = c.scene_object.name
                motion_data = c.get_json_data()
                print("upload motion clip ", name, "to ", c_id, c_name, c_type,
                      skeleton_name)
                semantic_annotation = c._motion._semantic_annotation
                meta_info = dict()
                if len(semantic_annotation) > 0:
                    meta_info[
                        "sections"] = create_section_dict_from_annotation(
                            semantic_annotation)
                time_function = c._motion._time_function
                if time_function is not None and is_processed:
                    meta_info["time_function"] = time_function
                else:
                    is_processed = False

                if len(meta_info) > 0:
                    meta_info_str = json.dumps(meta_info)
                else:
                    meta_info_str = ""
                upload_motion_to_db(self.db_url,
                                    name,
                                    motion_data,
                                    c_id,
                                    skeleton_name,
                                    meta_info_str,
                                    is_processed,
                                    session=self.session)
            self.close()

    def slot_reject(self):
        self.close()

    def slot_new_skeleton(self):
        dialog = NewSkeletonDialog()
        dialog.exec_()
        if dialog.success:
            name = dialog.name
            bvh_str = dialog.bvh_str
            model = dialog.skeleton_model_str
            if model == "" and name in SKELETON_MODELS:
                model = json.dumps(SKELETON_MODELS[name])
            create_new_skeleton_in_db(self.db_url, name, bvh_str, model)
            self.fill_combo_box_with_skeletons()
            self._fill_motion_list_from_db()