def test_set_and_get_token(self): board = BoardModel(3) board.set_token(0, 0, 'white') board.set_token(2, 1, 'black') self.assertEqual('black', board.get_token(2, 1)) self.assertEqual('white', board.get_token(0, 0)) self.assertEqual('empty', board.get_token(1, 1))
def __init__(self, host='', port=2222): self.host = host # Symbolic name meaning all available interfaces self.port = port # Arbitrary non-privileged port self.network_data = None # Datagram (udp) socket try : self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) print('Socket created') except socket.error as exp : print('Failed to create socket. Because: %s', str(exp)) raise # Bind socket to local host and port try: self.socket.bind((self.host, self.port)) print('Socket bind complete.') except socket.error as exp: print('Failed to bind the socket. Because: %s', str(exp)) raise try: self.db_connection = sqlite3.connect(DB_PATH) self.db_connection_cursor = self.db_connection.cursor() print('Data base connected.') except Exception as exp: print('Failed to connect to the database. Because: %s', str(exp)) raise self.board_model = BoardModel(self.get_all_device_list())
def test_get_neighbours(self): board = BoardModel(3) self.assertEqual( [(0, 1), (1, 0), (1, 2), (2, 1)], sorted(board.get_neighbours(1, 1))) self.assertEqual( [(0, 1), (1, 0)], sorted(board.get_neighbours(0, 0)))
def test_on_board(self): board = BoardModel(3) self.assertTrue(board.on_board(0, 0)) self.assertTrue(board.on_board(2, 1)) self.assertFalse(board.on_board(-1, 0)) self.assertFalse(board.on_board(0, 3)) self.assertFalse(board.on_board(3, 0)) self.assertFalse(board.on_board(2, -2))
def test_str_and_unicode(self): board = BoardModel(3) board.set_token(0, 0, 'white') board.set_token(2, 1, 'black') board_text = ( u"w e e\n" u"e e e\n" u"e b e") self.assertEqual(board_text, unicode(board)) self.assertEqual(board_text, str(board))
def newgame(self): '''Creates a new game based on the player's options''' player1AI = None player2AI = None model = BoardModel( width=int(self.width.get()), height=int(self.height.get()), k=int(self.k.get()), gravity=True if self.gravity.get() == "On" else False) #Setup human or AI player if (self.player1.get()): p1 = self.listbox_p1_AI.get() if len(p1) != 0: player1AI = p1 #Load AI Player else: raise NoAISelectedError("Select file for plater 1 AI.") if (self.player2.get()): p2 = self.listbox_p2_AI.get() if len(p2) != 0: player2AI = p2 #Load AI Player else: raise NoAISelectedError("Select file for plater 2 AI.") self.destroy() self.parent.destroy() create_newgame(model, player1AI, player2AI)
def test_board_from_string(self): board_string = ( "w e e\n" "e e e\n" "e b e") board = BoardModel.from_string(board_string) self.assertEqual(board_string, str(board))
def setUp(self): self.board_string = ( "w e e\n" "e b e\n" "w w b") self.board = BoardModel.from_string(self.board_string) self.game_state = GameState() self.game_state.board = self.board
def test_is_dead(self): board_string = ( "b b w e e\n" "b w e w e\n" "w b b e w\n" "e w w b b\n" "e e b w w") board = BoardModel.from_string(board_string) self.assertTrue(board.is_dead(0, 0)) self.assertFalse(board.is_dead(0, 3)) self.assertTrue(board.is_dead(4, 4)) self.assertFalse(board.is_dead(3, 0)) board_string = ( "e e e\n" "e b e\n" "e e e") board = BoardModel.from_string(board_string) self.assertFalse(board.is_dead(1, 1))
def setUp(self): self.board_string = ( "w e e\n" "w b e\n" "w w b") self.board = BoardModel.from_string(self.board_string) self.game_state = GameState() self.game_state.board = self.board self.game_state.stage = "dead stones removing"
def setUp(self): self.score_area = AreaScoring() self.game_state = GameState() self.game_state.board = BoardModel.from_string( "e e w e\n" "w e w b\n" "b w b e\n" "e b e e") self.game_state.stage = "dead stones removing" self.captives_count = { "black": 15, "white": 15 }
def __init__(self, app): QMainWindow.__init__(self, None) self.app = app self.boardModel = BoardModel(self.app) self._setupUi() self._refreshActionsState() self.connect(self.browserView.selectionModel(), SIGNAL('selectionChanged(QItemSelection,QItemSelection)'), self.browserSelectionChanged) self.connect(self.app, SIGNAL('boardChanged()'), self.boardChanged) # Actions self.connect(self.actionActions, SIGNAL('triggered()'), self.actionsTriggered) self.connect(self.actionMaterialize, SIGNAL('triggered()'), self.materializeTriggered) self.connect(self.actionShowLocations, SIGNAL('triggered()'), self.showLocationsTriggered) self.connect(self.actionShowDetails, SIGNAL('triggered()'), self.showDetailsTriggered) self.connect(self.actionShowIgnoreBox, SIGNAL('triggered()'), self.showIgnoreBoxTriggered) self.connect(self.actionAddLocation, SIGNAL('triggered()'), self.addLocationTriggered) self.connect(self.actionRemoveLocation, SIGNAL('triggered()'), self.removeLocationTriggered) self.connect(self.actionUpdateLocation, SIGNAL('triggered()'), self.updateLocationTriggered) self.connect(self.actionQuit, SIGNAL('triggered()'), QCoreApplication.instance().quit) self.connect(self.actionNewFolder, SIGNAL('triggered()'), self.newFolderTriggered) self.connect(self.actionRemoveEmptyFolders, SIGNAL('triggered()'), self.removeEmptyFoldersTriggered) self.connect(self.actionRenameSelected, SIGNAL('triggered()'), self.renameSelectedTriggered) self.connect(self.actionMoveSelectedToIgnoreBox, SIGNAL('triggered()'), self.moveSelectedToIgnoreBoxTriggered) self.connect(self.actionSwitchConflictAndOriginal, SIGNAL('triggered()'), self.switchConflictAndOriginalTriggered) self.connect(self.actionMassRename, SIGNAL('triggered()'), self.massRenameTriggered) self.connect(self.actionSplit, SIGNAL('triggered()'), self.splitTriggered) self.connect(self.actionUndoSplit, SIGNAL('triggered()'), self.undoSplitTriggered) self.connect(self.actionMoveConflicts, SIGNAL('triggered()'), self.moveConflictsTriggered) self.connect(self.actionMoveConflictsAndOriginals, SIGNAL('triggered()'), self.moveConflictsAndOriginalsTriggered) self.connect(self.actionRenameInRespectiveLocations, SIGNAL('triggered()'), self.renameInRespectiveLocationsTriggered) self.connect(self.actionCopyToOtherLocation, SIGNAL('triggered()'), self.copyToOtherLocationTriggered) self.connect(self.actionMoveToOtherLocation, SIGNAL('triggered()'), self.moveToOtherLocationTriggered) self.connect(self.actionShowHelp, SIGNAL('triggered()'), self.showHelpTriggered) self.connect(self.actionRegister, SIGNAL('triggered()'), self.registerTrigerred) self.connect(self.actionCheckForUpdate, SIGNAL('triggered()'), self.checkForUpdateTriggered) self.connect(self.actionOpenDebugLog, SIGNAL('triggered()'), self.openDebugLogTriggered) self.connect(self.actionAbout, SIGNAL('triggered()'), self.aboutTriggered)
def test_remove_group(self): board_string = ( "b b w e e\n" "b w e w e\n" "w b b e w\n" "e w w b b\n" "e e b w w") board = BoardModel.from_string(board_string) self.assertEquals(3, deepcopy(board).remove_group(0, 0)) self.assertEquals(2, deepcopy(board).remove_group(3, 1)) self.assertEquals(0, deepcopy(board).remove_group(4, 0)) self.assertEquals(3, board.remove_group(0, 0)) self.assertEquals(( "e e w e e\n" "e w e w e\n" "w b b e w\n" "e w w b b\n" "e e b w w"), str(board))
def test_get_group(self): board_string = ( "b b w e e\n" "b w e w e\n" "w b b w w\n" "e w w w e\n" "e e e w e") board = BoardModel.from_string(board_string) self.assertEqual(([(0, 0), (0, 1), (1, 0)], ("white", )), board.get_group(0, 0)) self.assertEqual(([(2, 0)], ("black", "empty")), board.get_group(2, 0)) self.assertEqual(([(3, 4), (4, 4)], ("white", )), board.get_group(4, 4)) doctest.run_docstring_examples( BoardModel.get_group, {"BoardModel": BoardModel}, name="get_group")
def test_ko(self): board = BoardModel.from_string(( "e e e e\n" "e b w e\n" "b w e w\n" "e b w e")) self.game_state.board = board game_state = self.game_state move = PlaceStoneMove(2, 2) self.assertTrue(move.validate(game_state)) game_state = move(game_state) move = PlaceStoneMove(2, 1) self.assertFalse(move.validate(game_state)) move = PlaceStoneMove(0, 1) self.assertTrue(move.validate(game_state)) game_state = move(game_state) move = PlaceStoneMove(2, 1) self.assertTrue(move.validate(game_state))
def create_newgame(model=None, player1AI=None, player2AI=None, gui=True, stepmode=False): '''Creates a new game. If no_gui, both players must be AI players''' if not gui: '''No GUI''' if player1AI is not None and player2AI is not None: player1 = AIPlayer(1, model, player1AI) player2 = AIPlayer(2, model, player2AI) game = connectk.ConnectK(model, player1, player2) p = Thread(target=game.play) p.start() return else: raise NoGUIError( "If no GUI option is used, both players must be AIs.") else: '''GUI''' root = TK.Tk() if model is None: model = BoardModel() #New instance with default settings gui = ConnectKGUI(root, model) if stepmode: gui.stepmode.set(True) if player1AI is None: player1 = GUIPlayer(1, model) gui.add_button_listener(player1.action_listener, 1) else: player1 = AIPlayer(1, model, player1AI) if player2AI is None: player2 = GUIPlayer(2, model) gui.add_button_listener(player2.action_listener, 2) else: player2 = AIPlayer(2, model, player2AI) game = connectk.ConnectK(model, player1, player2, gui) p = Thread(target=game.play) gui.update_gui(time=2) p.start() root.mainloop()
class Sender: def __init__(self, host='192.168.1.1', port=2223): self.HOST = host # Symbolic name meaning all available interfaces self.PORT = port # Arbitrary non-privileged port # Datagram (udp) socket try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) print('Socket created') except socket.error as exp: print('Failed to create socket. Because: %s', str(exp)) raise # Bind socket to local host and port try: self.socket.bind(('', self.PORT)) print('Socket bind complete') except socket.error as exp: print('Failed to bind the socket. Because: %s', str(exp)) raise try: self.db_connection = sqlite3.connect(DB_PATH) self.db_cursor_connection = self.db_connection.cursor() print('Data base connected.') except Exception as exp: print('Failed to connect to the database. Because: %s', str(exp)) raise self.board_model = BoardModel(self.get_all_device_list()) def destruct(self): self.socket.close() self.db_connection.close() def get_all_device_list(self): res = self.db_connection.execute( "SELECT id,channel,pos,isAnalog FROM backend_accessories") res = [{ 'id': x[0], 'channel': x[1], 'pos': x[2], 'isAnalog': x[3] } for x in res] return res def get_device_status(self): res = self.db_connection.execute( "SELECT id,status,analogValue FROM backend_accessories") res = [{'id': x[0], 'status': x[1], 'analogValue': x[2]} for x in res] return res def print_changes(self): changes = self.board_model.get_changed_keys() if changes: for _, d in changes.items(): if d.type == 'hvac': print('%d) change hvac to %d (status=%d)' % (d.id, d.value, d.status)) elif d.type == 'key': print('%d) change key to %d' % (d.id, d.status)) def send_payload(self): if DEBUG: print('sending: ', [r for r in self.board_model.to_byte_array()]) res = self.socket.sendto(self.board_model.to_byte_array(), (self.HOST, self.PORT)) if res and res != 14 and DEBUG: res_text = (' (%s)' % error_list[res]) if res in error_list else '' print('send-to function fail: %d%s' % (res, res_text)) def send(self): status_list = self.get_device_status() self.board_model.load_status(status_list) self.print_changes() self.send_payload()
class Receiver: def __init__(self, host='', port=2222): self.host = host # Symbolic name meaning all available interfaces self.port = port # Arbitrary non-privileged port self.network_data = None # Datagram (udp) socket try : self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) print('Socket created') except socket.error as exp : print('Failed to create socket. Because: %s', str(exp)) raise # Bind socket to local host and port try: self.socket.bind((self.host, self.port)) print('Socket bind complete.') except socket.error as exp: print('Failed to bind the socket. Because: %s', str(exp)) raise try: self.db_connection = sqlite3.connect(DB_PATH) self.db_connection_cursor = self.db_connection.cursor() print('Data base connected.') except Exception as exp: print('Failed to connect to the database. Because: %s', str(exp)) raise self.board_model = BoardModel(self.get_all_device_list()) def get_all_device_list(self): res = self.db_connection.execute("SELECT id,channel,pos,isAnalog FROM backend_accessories") res = [{'id': x[0], 'channel': x[1], 'pos': x[2], 'isAnalog': x[3]} for x in res] return res def get_device_status(self): res = self.db_connection.execute("SELECT id,status,analogValue,isActive FROM backend_accessories") res = [{'id': x[0], 'status': x[1], 'analogValue': x[2], 'isActive': x[3]} for x in res] # FIXME: make digital status only boolean return res def destruct(self): self.socket.close() self.db_connection.close() def update_data_from_network(self): data, addr = self.socket.recvfrom(1024) if not data: raise Exception('invalid data recieved.') self.network_data = bytearray(data.strip()) def apply_changes(self): changed_keys = self.board_model.get_changed_keys() if changed_keys: for _, k in changed_keys.items(): if k.type == 'key': self.set_key_on_db(k.id, k.status) elif k.type == 'hvac': self.set_hvac_on_db(k.id, k.status) self.db_connection.commit() def process_key_channel(self, channel_id, channel_payload): for pos in range(8): val = channel_payload & (1 << pos) try: self.board_model.set_key_by_channel_pos((channel_id, pos), val) except KeyError: pass def process_net_data(self): # process keys for i in range(1, 8): self.process_key_channel(i, self.network_data[i]) # process hvacs for i in range(8, 14): try: self.board_model.set_hvac_by_channel(i, self.network_data[i]) except KeyError: pass def cycle(self): status_list = self.get_device_status() self.board_model.load_status(status_list) self.board_model.reset_changes() self.update_data_from_network() self.process_net_data() self.apply_changes() def set_key_on_db(self, id, value): print('toggeling %d to %d' % (id, value)) self.db_connection.execute('UPDATE backend_accessories SET status=%d WHERE id=%d' % (value, id)) def set_hvac_on_db(self, id, value): self.db_connection.execute('UPDATE backend_accessories SET status=%d WHERE id=%d' % (value, id))
def test_validate_dead_stone(self): self.game_state.board = BoardModel.from_string( "e w e\n" "w w w\n" "e b b") self.assertFalse(PlaceStoneMove(2, 0).validate(self.game_state))
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self, app): QMainWindow.__init__(self, None) self.app = app self.boardModel = BoardModel(self.app) self._setupUi() self._refreshActionsState() self.connect(self.browserView.selectionModel(), SIGNAL('selectionChanged(QItemSelection,QItemSelection)'), self.browserSelectionChanged) self.connect(self.app, SIGNAL('boardChanged()'), self.boardChanged) # Actions self.connect(self.actionActions, SIGNAL('triggered()'), self.actionsTriggered) self.connect(self.actionMaterialize, SIGNAL('triggered()'), self.materializeTriggered) self.connect(self.actionShowLocations, SIGNAL('triggered()'), self.showLocationsTriggered) self.connect(self.actionShowDetails, SIGNAL('triggered()'), self.showDetailsTriggered) self.connect(self.actionShowIgnoreBox, SIGNAL('triggered()'), self.showIgnoreBoxTriggered) self.connect(self.actionAddLocation, SIGNAL('triggered()'), self.addLocationTriggered) self.connect(self.actionRemoveLocation, SIGNAL('triggered()'), self.removeLocationTriggered) self.connect(self.actionUpdateLocation, SIGNAL('triggered()'), self.updateLocationTriggered) self.connect(self.actionQuit, SIGNAL('triggered()'), QCoreApplication.instance().quit) self.connect(self.actionNewFolder, SIGNAL('triggered()'), self.newFolderTriggered) self.connect(self.actionRemoveEmptyFolders, SIGNAL('triggered()'), self.removeEmptyFoldersTriggered) self.connect(self.actionRenameSelected, SIGNAL('triggered()'), self.renameSelectedTriggered) self.connect(self.actionMoveSelectedToIgnoreBox, SIGNAL('triggered()'), self.moveSelectedToIgnoreBoxTriggered) self.connect(self.actionSwitchConflictAndOriginal, SIGNAL('triggered()'), self.switchConflictAndOriginalTriggered) self.connect(self.actionMassRename, SIGNAL('triggered()'), self.massRenameTriggered) self.connect(self.actionSplit, SIGNAL('triggered()'), self.splitTriggered) self.connect(self.actionUndoSplit, SIGNAL('triggered()'), self.undoSplitTriggered) self.connect(self.actionMoveConflicts, SIGNAL('triggered()'), self.moveConflictsTriggered) self.connect(self.actionMoveConflictsAndOriginals, SIGNAL('triggered()'), self.moveConflictsAndOriginalsTriggered) self.connect(self.actionRenameInRespectiveLocations, SIGNAL('triggered()'), self.renameInRespectiveLocationsTriggered) self.connect(self.actionCopyToOtherLocation, SIGNAL('triggered()'), self.copyToOtherLocationTriggered) self.connect(self.actionMoveToOtherLocation, SIGNAL('triggered()'), self.moveToOtherLocationTriggered) self.connect(self.actionShowHelp, SIGNAL('triggered()'), self.showHelpTriggered) self.connect(self.actionRegister, SIGNAL('triggered()'), self.registerTrigerred) self.connect(self.actionCheckForUpdate, SIGNAL('triggered()'), self.checkForUpdateTriggered) self.connect(self.actionOpenDebugLog, SIGNAL('triggered()'), self.openDebugLogTriggered) self.connect(self.actionAbout, SIGNAL('triggered()'), self.aboutTriggered) def _setupUi(self): self.setupUi(self) self.browserView.setModel(self.boardModel) h = self.browserView.header() h.setResizeMode(QHeaderView.Fixed) h.resizeSection(1, 120) h.setResizeMode(0, QHeaderView.Stretch) # Action menu actionMenu = QMenu('Actions', self.toolBar) actionMenu.setIcon(QIcon(QPixmap(":/actions"))) actionMenu.addAction(self.actionNewFolder) actionMenu.addAction(self.actionRemoveEmptyFolders) actionMenu.addAction(self.actionRenameSelected) actionMenu.addAction(self.actionMoveSelectedToIgnoreBox) actionMenu.addAction(self.actionSwitchConflictAndOriginal) actionMenu.addSeparator() actionMenu.addAction(self.actionMassRename) actionMenu.addAction(self.actionSplit) actionMenu.addAction(self.actionUndoSplit) actionMenu.addAction(self.actionMoveConflicts) actionMenu.addAction(self.actionMoveConflictsAndOriginals) self.actionActions.setMenu(actionMenu) button = QToolButton(self.toolBar) button.setDefaultAction(actionMenu.menuAction()) button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.actionsButton = button self.toolBar.insertWidget(self.actionActions, button) # the action is a placeholder self.toolBar.removeAction(self.actionActions) # Materialize menu materializeMenu = QMenu('Materialize', self.toolBar) materializeMenu.setIcon(QIcon(QPixmap(":/materialize"))) materializeMenu.addAction(self.actionRenameInRespectiveLocations) materializeMenu.addAction(self.actionCopyToOtherLocation) materializeMenu.addAction(self.actionMoveToOtherLocation) self.actionMaterialize.setMenu(materializeMenu) button = QToolButton(self.toolBar) button.setDefaultAction(materializeMenu.menuAction()) button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.materializeButton = button self.toolBar.insertWidget(self.actionMaterialize, button) # the action is a placeholder self.toolBar.removeAction(self.actionMaterialize) def _refreshActionsState(self): boardEmpty = len(self.app.board) == 0 hasConflicts = len(self.app.board.allconflicts) > 0 hasSelection = len(self.app.selectedBoardItems) > 0 selectedIsConflicted = False if hasSelection: node = self.app.selectedBoardItems[0] selectedIsConflicted = is_conflicted(node.name) boardIsSplit = self.app.board.splitted for action in [self.actionMassRename, self.actionNewFolder, self.actionRemoveEmptyFolders, self.actionRenameInRespectiveLocations, self.actionCopyToOtherLocation, self.actionMoveToOtherLocation]: action.setEnabled(not boardEmpty) self.actionMoveConflicts.setEnabled(not boardEmpty and hasConflicts) self.actionMoveConflictsAndOriginals.setEnabled(not boardEmpty and hasConflicts) self.actionSwitchConflictAndOriginal.setEnabled(not boardEmpty and selectedIsConflicted) self.actionRenameSelected.setEnabled(not boardEmpty and hasSelection) self.actionMoveSelectedToIgnoreBox.setEnabled(not boardEmpty and hasSelection) self.actionSplit.setEnabled(not boardEmpty and not boardIsSplit) self.actionUndoSplit.setEnabled(not boardEmpty and boardIsSplit) #--- Actions def aboutTriggered(self): self.app.showAboutBox() def actionsTriggered(self): self.actionsButton.showMenu() def addLocationTriggered(self): self.app.addLocationPrompt() def checkForUpdateTriggered(self): QProcess.execute('updater.exe', ['/checknow']) def copyToOtherLocationTriggered(self): self.app.copyOrMove(copy=True) def massRenameTriggered(self): dialog = MassRenameDialog(self.app) result = dialog.exec_() if result == QDialog.Accepted: self.app.massRename(dialog.model, dialog.whitespace) def materializeTriggered(self): self.materializeButton.showMenu() def moveConflictsTriggered(self): self.app.moveConflicts() def moveConflictsAndOriginalsTriggered(self): self.app.moveConflicts(with_original=True) def moveSelectedToIgnoreBoxTriggered(self): self.app.moveSelectedToIgnoreBox() def moveToOtherLocationTriggered(self): self.app.copyOrMove(copy=False) def newFolderTriggered(self): # We're not using browserView.currentIndex as a base index here because it's impossible # for the user to set the currentIndex to "None" after a node has been selected (even if # you deselect all nodes, the current index will stay on the last selected node). selectedIndexes = self.browserView.selectionModel().selectedRows() currentIndex = selectedIndexes[0] if selectedIndexes else QModelIndex() parent = currentIndex.internalPointer().ref if currentIndex.isValid() else self.app.board newname = self.app.new_folder(parent) self.boardModel.insertRow(0, currentIndex) parentNode = currentIndex.internalPointer() if currentIndex.isValid() else self.boardModel for node in parentNode.subnodes: if node.ref.name == newname: index = node.index self.browserView.setCurrentIndex(index) self.browserView.edit(index) break def openDebugLogTriggered(self): debugLogPath = op.join(self.app.appdata, 'debug.log') url = QUrl.fromLocalFile(debugLogPath) QDesktopServices.openUrl(url) def registerTrigerred(self): self.app.askForRegCode() def removeEmptyFoldersTriggered(self): self.app.removeEmptyFolders() def removeLocationTriggered(self): self.app.removeLocationPrompt() def renameInRespectiveLocationsTriggered(self): self.app.renameInRespectiveLocations() def renameSelectedTriggered(self): selectedIndexes = self.browserView.selectionModel().selectedRows() if not selectedIndexes: return index = selectedIndexes[0] self.browserView.setCurrentIndex(index) self.browserView.edit(index) def showDetailsTriggered(self): self.app.showDetailsPanel() def showHelpTriggered(self): self.app.showHelp() def showIgnoreBoxTriggered(self): self.app.showIgnoreBox() def showLocationsTriggered(self): self.app.showLocationPanel() def splitTriggered(self): dialog = SplitDialog(self.app) result = dialog.exec_() if result == QDialog.Accepted: self.app.split(dialog.model, dialog.capacity, dialog.grouping_level) def switchConflictAndOriginalTriggered(self): currentIndex = self.browserView.currentIndex() if not currentIndex.isValid(): return currentNode = currentIndex.internalPointer() self.app.SwitchConflictAndOriginal(currentNode.ref) self.boardModel.refreshNode(currentNode.parent) newIndex = self.boardModel.index(currentIndex.row(), currentIndex.column(), currentNode.parent.index) self.browserView.setCurrentIndex(newIndex) def undoSplitTriggered(self): self.app.undoSplit() def updateLocationTriggered(self): if self.app.selectedLocation is not None: self.app.updateLocation(self.app.selectedLocation) #--- Events def boardChanged(self): self.app.selectBoardItems([]) self._refreshActionsState() def browserSelectionChanged(self, selected, deselected): selectedIndexes = self.browserView.selectionModel().selectedRows() nodes = [index.internalPointer() for index in selectedIndexes] items = [node.ref for node in nodes] self.app.selectBoardItems(items) self._refreshActionsState()