class MapView(QGraphicsView): """A map of reaction boxes""" def __init__(self, appdata: CnaData, name: str): self.scene = QGraphicsScene() QGraphicsView.__init__(self, self.scene) palette = self.palette() palette.setColor(QPalette.Base, Qt.white) self.setPalette(palette) self.appdata = appdata self.name = name self.setAcceptDrops(True) self.drag = False self.reaction_boxes: Dict[str, ReactionBox] = {} self._zoom = 0 self.drag = False self.drag_start = None # initial scale self._zoom = self.appdata.project.maps[self.name]["zoom"] if self._zoom > 0: for _ in range(1, self._zoom): self.scale(INCREASE_FACTOR, INCREASE_FACTOR) if self._zoom < 0: for _ in range(self._zoom, -1): self.scale(DECREASE_FACTOR, DECREASE_FACTOR) # connect events to methods self.horizontalScrollBar().valueChanged.connect(self.on_hbar_change) self.verticalScrollBar().valueChanged.connect(self.on_vbar_change) def on_hbar_change(self, x): self.appdata.project.maps[self.name]["pos"] = ( x, self.verticalScrollBar().value()) def on_vbar_change(self, y): self.appdata.project.maps[self.name]["pos"] = ( self.horizontalScrollBar().value(), y) def dragEnterEvent(self, event: QGraphicsSceneDragDropEvent): event.setAccepted(True) event.accept() event.acceptProposedAction() def dragMoveEvent(self, event: QGraphicsSceneDragDropEvent): event.setAccepted(True) point = event.pos() point_item = self.mapToScene(point) r_id = event.mimeData().text() if r_id in self.appdata.project.maps[self.name]["boxes"].keys(): self.appdata.project.maps[self.name]["boxes"][r_id] = ( point_item.x(), point_item.y()) self.mapChanged.emit(r_id) else: self.appdata.project.maps[self.name]["boxes"][r_id] = ( point_item.x(), point_item.y()) self.reactionAdded.emit(r_id) self.update() def dragLeaveEvent(self, _event): self.update() def dropEvent(self, event: QGraphicsSceneDragDropEvent): self.drag = False point = event.pos() point_item = self.mapToScene(point) identifier = event.mimeData().text() self.appdata.project.maps[self.name]["boxes"][identifier] = ( point_item.x(), point_item.y()) self.mapChanged.emit(identifier) self.update() def wheelEvent(self, event): modifiers = QApplication.queryKeyboardModifiers() if modifiers == Qt.ControlModifier: if event.angleDelta().y() > 0: self.appdata.project.maps[ self.name]["bg-size"] *= INCREASE_FACTOR else: self.appdata.project.maps[ self.name]["bg-size"] *= DECREASE_FACTOR self.mapChanged.emit("dummy") self.update() if event.angleDelta().y() > 0: self.zoom_in() else: self.zoom_out() def fit(self): self.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio) def zoom_in(self): self._zoom += 1 self.appdata.project.maps[self.name]["zoom"] = self._zoom self.scale(INCREASE_FACTOR, INCREASE_FACTOR) def zoom_out(self): self._zoom -= 1 self.appdata.project.maps[self.name]["zoom"] = self._zoom self.scale(DECREASE_FACTOR, DECREASE_FACTOR) def mousePressEvent(self, event: QMouseEvent): self.drag = True self.drag_start = event.pos() super(MapView, self).mousePressEvent(event) def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent): modifiers = QApplication.queryKeyboardModifiers() if modifiers == Qt.ControlModifier: if self.drag: point = event.pos() move_x = self.drag_start.x() - point.x() move_y = self.drag_start.y() - point.y() self.drag_start = point for key, val in self.appdata.project.maps[ self.name]["boxes"].items(): self.appdata.project.maps[self.name]["boxes"][key] = ( val[0] - move_x, val[1] - move_y) self.mapChanged.emit("dummy") self.update() else: if self.drag: self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) self.translate(1, 1) super(MapView, self).mouseMoveEvent(event) def mouseReleaseEvent(self, event: QMouseEvent): if self.drag: self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) self.translate(1, 1) self.drag = False super(MapView, self).mouseReleaseEvent(event) def update_selected(self, string): for r_id in self.reaction_boxes: if string.lower() in r_id.lower(): self.reaction_boxes[r_id].item.setHidden(False) elif string.lower() in self.reaction_boxes[r_id].name.lower(): self.reaction_boxes[r_id].item.setHidden(False) else: self.reaction_boxes[r_id].item.setHidden(True) def focus_reaction(self, reaction: str): x = self.appdata.project.maps[self.name]["boxes"][reaction][0] y = self.appdata.project.maps[self.name]["boxes"][reaction][1] self.centerOn(x, y) def highlight_reaction(self, string): # hide other boxes # for id in self.reaction_boxes: # self.reaction_boxes[id].item.setHidden(True) treffer = self.reaction_boxes[string] treffer.item.setHidden(False) treffer.set_color(Qt.magenta) def update(self): self.scene.clear() background = QGraphicsSvgItem( self.appdata.project.maps[self.name]["background"]) background.setFlags(QGraphicsItem.ItemClipsToShape) background.setScale(self.appdata.project.maps[self.name]["bg-size"]) self.scene.addItem(background) for r_id in self.appdata.project.maps[self.name]["boxes"]: try: name = self.appdata.project.cobra_py_model.reactions.get_by_id( r_id).name box = ReactionBox(self, r_id, name) box.setPos( self.appdata.project.maps[self.name]["boxes"][r_id][0], self.appdata.project.maps[self.name]["boxes"][r_id][1]) self.scene.addItem(box) self.reaction_boxes[r_id] = box except KeyError: print("failed to add reaction box for", r_id) self.set_values() # set scrollbars self.horizontalScrollBar().setValue( self.appdata.project.maps[self.name]["pos"][0]) self.verticalScrollBar().setValue( self.appdata.project.maps[self.name]["pos"][1]) def set_values(self): for r_id in self.appdata.project.maps[self.name]["boxes"]: if r_id in self.appdata.project.scen_values.keys(): self.reaction_boxes[r_id].set_val_and_color( self.appdata.project.scen_values[r_id]) elif r_id in self.appdata.project.comp_values.keys(): self.reaction_boxes[r_id].set_val_and_color( self.appdata.project.comp_values[r_id]) def remove_box(self, reaction: str): del self.appdata.project.maps[self.name]["boxes"][reaction] del self.reaction_boxes[reaction] self.update() self.reactionRemoved.emit(reaction) # def emit_doubleClickedReaction(self, reaction: str): # print("emit_doubleClickedReaction") # self.doubleClickedReaction.emit(reaction) def value_changed(self, reaction: str, value: str): self.reactionValueChanged.emit(reaction, value) self.reaction_boxes[reaction].recolor() switchToReactionMask = Signal(str) maximizeReaction = Signal(str) minimizeReaction = Signal(str) reactionRemoved = Signal(str) reactionValueChanged = Signal(str, str) reactionAdded = Signal(str) mapChanged = Signal(str)
class MovieSelectionWindow(QDialog): __scene__ = None __poster_url__ = 'https://image.tmdb.org/t/p/original' __possibilities__ = None acceptedId = -1 def __init__(self, oFile, possibilities): self.acceptedId = -1 QDialog.__init__(self) self.ui = Ui_MovieSelection() self.ui.setupUi(self) self.ui.btnEnterId.clicked.connect(self.enterId) self.ui.btnEnterTitle.clicked.connect(self.enterTitle) self.ui.btnAccept.clicked.connect(self.accept) self.ui.tablePossibilities.horizontalHeader().setVisible(True) self.ui.tablePossibilities.verticalHeader().setVisible(True) self.ui.tablePossibilities.cellClicked.connect(self.selectionChanged) self.ui.lblOriginalFile.setText(oFile) self.__possibilities__ = possibilities self.actualizeTable() def showImage(self, posterPath: str): self.removeImage() imgData = requests.get(self.__poster_url__ + posterPath) pix = QPixmap() pix.loadFromData(imgData.content) item = QGraphicsPixmapItem(pix) self.__scene__ = QGraphicsScene(self) self.__scene__.addItem(item) self.ui.graphicsView.setScene(self.__scene__) self.resizeImage() def removeImage(self): if self.__scene__ != None: self.__scene__.clear() self.__scene__ = None def resizeEvent(self, event): QDialog.resizeEvent(self, event) self.resizeImage() def resizeImage(self): if (self.__scene__ != None): self.ui.graphicsView.fitInView(self.__scene__.sceneRect(), mode=Qt.KeepAspectRatio) self.ui.graphicsView.show() def actualizeTable(self): self.ui.tablePossibilities.clearContents() r = 0 for p in self.__possibilities__: if 'title' not in p.__dict__ or 'release_date' not in p.__dict__: self.__possibilities__.remove(p) continue self.ui.tablePossibilities.setRowCount(r + 1) self.ui.tablePossibilities.setItem(r, 0, QTableWidgetItem(p.title)) self.ui.tablePossibilities.setItem( r, 1, QTableWidgetItem(p.release_date[:4])) r += 1 self.ui.tablePossibilities.clearSelection() def selectionChanged(self, row, column): self.ui.txtOverview.clear() self.ui.txtOverview.appendPlainText( self.__possibilities__[row].overview) self.ui.lblTitle.setText(self.__possibilities__[row].title + ' (' + self.__possibilities__[row].release_date[:4] + ')') if self.__possibilities__[row].poster_path != None: self.showImage(self.__possibilities__[row].poster_path) else: self.removeImage() def enterId(self): select = CustomEnterWindow(True) select.setWindowModality(Qt.WindowModal) mw = qtmodern.windows.ModernWindow(select) mw.setWindowModality(Qt.WindowModal) mw.show() select.ui.txtId.setFocus() loop = QEventLoop() select.finished.connect(loop.quit) loop.exec() if select.result != None and select.result.isdecimal(): self.acceptedId = int(select.result) self.close() def __enterTitleWindow__(self, search): select = CustomEnterWindow(False) select.setWindowModality(Qt.WindowModal) mw = qtmodern.windows.ModernWindow(select) mw.setWindowModality(Qt.WindowModal) mw.show() select.ui.txtId.setFocus() loop = QEventLoop() select.finished.connect(loop.quit) loop.exec() if select.result != None: self.__possibilities__ = search(select.result) self.actualizeTable() def enterTitle(self): self.__enterTitleWindow__(Movie().search) def accept(self): self.acceptedId = self.__possibilities__[ self.ui.tablePossibilities.currentRow()].id self.close()