def __init__(self, delphi, campaign, archive_meta=None): super().__init__(None) self.delphi = delphi self.campaign = campaign self.archive_meta = archive_meta self.dirty = True campaign_db_path = self.database_path(campaign) self._engine = create_engine("sqlite:///{}".format(campaign_db_path), echo=True) self._Session = sessionmaker(bind=self._engine) GameBase.metadata.create_all(self._engine) CampaignBase.metadata.create_all(self._engine) self.view = CampaignWindow(self.campaign) self.map_controller = None self.player_controller = None self.session_controller = None self.search_controller = None self._init_subcontrollers() asset_tree = self.build_asset_tree() self.asset_tree_model = TreeModel(asset_tree) self._init_view()
class CampaignController(QtController): """ A ``CampaignController`` is the controller for a campaign during the lifetime of an application. To keep this class small, it is mostly responsible for managing the highest level logic on a campaign and delegating operations to sub-controllers. ``CampaignController`` instances operate on already existing campaigns. The creation of, for example, the working directory for the campaign is expected to be handled externally, e.g. by the ``AppController`` or test harnesses. """ def __init__(self, delphi, campaign, archive_meta=None): super().__init__(None) self.delphi = delphi self.campaign = campaign self.archive_meta = archive_meta self.dirty = True campaign_db_path = self.database_path(campaign) self._engine = create_engine("sqlite:///{}".format(campaign_db_path), echo=True) self._Session = sessionmaker(bind=self._engine) GameBase.metadata.create_all(self._engine) CampaignBase.metadata.create_all(self._engine) self.view = CampaignWindow(self.campaign) self.map_controller = None self.player_controller = None self.session_controller = None self.search_controller = None self._init_subcontrollers() asset_tree = self.build_asset_tree() self.asset_tree_model = TreeModel(asset_tree) self._init_view() def db(self): """ :return: A session to the database. """ self._Session.configure(bind=self._engine) return self._Session() @staticmethod def working_directory(campaign): """ Return an absolute path to the working directory for the campaign, usually ``TEMP_DIR/{campaign.id}/``. """ return os.path.join(TMP_PATH, str(campaign.id)) @staticmethod def extracted_archive_path(campaign): return os.path.join(CampaignController.working_directory(campaign), "archive") @staticmethod def database_path(campaign): return os.path.join( CampaignController.extracted_archive_path(campaign), "campaign.db") @staticmethod def build_context_menu(listing, name): context_menu = QMenu(name) for action in listing: context_menu.addAction(action) return context_menu @staticmethod def xapian_database_path(campaign): return os.path.join(CampaignController.working_directory(campaign), "oracle") def _init_subcontrollers(self): self.map_controller = MapController(self) self.player_controller = PlayerController(self) self.note_controller = NoteController(self) self.session_controller = SessionController(self) self.search_controller = SearchController(self.delphi, SearchCompleter()) def _init_view(self): sc = self.search_controller v = self.view v.save_campaign.triggered.connect(self.on_sync_campaign) v.save_campaign_as.triggered.connect(self.on_save_campaign_as) v.searchEdit.textChanged.connect(sc.on_search_text_changed) v.searchEdit.returnPressed.connect(sc.on_search_requested) v.assetTree.setModel(self.asset_tree_model) v.assetTree.clicked.connect(lambda idx: log.debug( "idx = %s, %s", idx, self.asset_tree_model.rowCount(idx))) v.assetTree.doubleClicked.connect(self.asset_tree_doubleclick) v.assetTree.customContextMenuRequested.connect( self.asset_tree_context_menu_requested) v.campaign_properties.triggered.connect(self.on_campaign_properties) def build_asset_tree(self): root = FixedNode(*[ controller.tree_node for controller in [ self.map_controller, self.session_controller, self.player_controller, self.note_controller ] ]) return root def window_moved(self): """Called when the main campaign window is moved.""" self.search_controller.update_results_popup() def asset_tree_doubleclick(self, index): node = index.internalPointer() if node.action: node.action(node) elif node.parent and node.parent.item_action: node.parent.item_action(node) @pyqtSlot(QPoint) def asset_tree_context_menu_requested(self, point): index = self.view.assetTree.indexAt(point) node = index.internalPointer() if node is None: return controller = node.delegate if not controller: log.debug("There is no controller on this node.") return context_menu = CampaignController.build_context_menu( controller.context_menu(), "Asset tree context menu") context_menu.exec(controller.view.mapToGlobal(point)) @pyqtSlot() def on_sync_campaign(self): log.debug("requested to sync campaign") am = self.archive_meta if not am: self._save_campaign_as() return path = am.last_seen_path if am.last_seen_path and not os.path.exists(am.last_seen_path): # TODO why do we do this? I forget the original use case. display_warning( self.view, "The campaign archive appears to have " "been moved or deleted.\n\nPlease " "select a new location to save this " "archive.") path = self._save_campaign_as() if not path: return self._sync_archive_meta(path) archive.export( self.archive_meta, CampaignController.extracted_archive_path(self.campaign), am.last_seen_path) @pyqtSlot() def on_save_campaign_as(self): self._save_campaign_as() @pyqtSlot() def on_campaign_properties(self): dlg = CampaignPropertiesDialog(self.campaign, self.view) dlg.accepted.connect(lambda: self.on_properties_update(dlg)) dlg.show() @pyqtSlot() def on_properties_update(self, propdlg): options = propdlg.options for k, v in options.items(): setattr(self.campaign, k, v) self.view.setWindowTitle(self.campaign.name) self.properties_dialog = None def _save_campaign_as(self): path = get_save_filename(self.view, "Save campaign as", filter_=filters.campaign) if not path: return try: self._sync_archive_meta(path) archive.export( self.archive_meta, CampaignController.extracted_archive_path(self.campaign), path) except OSError as e: log.error("could not export campaign: %s", e) else: return path def _sync_archive_meta(self, path): campaign = self.campaign self.archive_meta = ArchiveMeta(campaign.id, campaign.game_system.id, campaign.name, campaign.description, campaign.author, campaign.creation_date, campaign.revision_date, last_seen_path=path)
def getParentTree(id): tree = TreeModel.searchParent(id) return jsonify(tree)
def index(): userAvailable = TreeModel.getUserAvailable() return render_template('tree/tree.html', userAvailable=userAvailable)
def getUplineTree(id): tree = TreeModel.searchNetworkUp(id) return jsonify(tree)
def getDownlineTree(id): tree = TreeModel.searchNetworkDown(id) return jsonify(tree)
def getDataTree(): tree = TreeModel.getTree() return jsonify(tree)
def saveTree(): try: TreeModel.insertTree(request) except: print('ERRORS') return redirect('/')
def foomodel(self, foodb): root = TableNode(foodb, FooTableClass, text="Foo") model = TreeModel(root) return model
def attr_model(attr_tree): return TreeModel(attr_tree)
def test_flags(self): model = TreeModel(FixedNode()) assert model.flags(QModelIndex()) == (Qt.ItemIsEnabled | Qt.ItemIsSelectable)
def test_title_header_data(self): model = TreeModel(FixedNode(), title="FooHeader") assert model.headerData(0, Qt.Horizontal) == "FooHeader" assert model.headerData(0, Qt.Vertical) == QVariant()
def tree_model(big_fixed_node_tree): return TreeModel(big_fixed_node_tree)