Skip to content

Commit 0b77aff

Browse files
committed
make it possible to reset the application, allowing to switch images
1 parent a50cef4 commit 0b77aff

File tree

7 files changed

+63
-16
lines changed

7 files changed

+63
-16
lines changed

src/backend/rule_manager.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,13 @@ def getRules(self) -> List[str]:
5858
return list(self._config.keys())
5959

6060
@staticmethod
61-
def _getFileBase(filename):
62-
# remove mime type and check it if exists
61+
def _getFileBase(filename: str):
62+
# remove .rules mime type
63+
if filename.startswith("."):
64+
raise ValueError("rules are not allowed to start with .")
6365
splits = filename.split(".")
64-
if len(splits) > 2:
65-
raise ValueError("The name must have format <rule> or <rule>.rules")
66-
if len(splits) == 2:
67-
if splits[1] != "rules":
68-
raise ValueError(f"Unknown rule mime type '{splits[1]}'")
69-
filename = splits[0]
66+
if len(splits) >= 2 and splits[-1] == "rules":
67+
filename = ".".join(splits[0:-1])
7068
return filename
7169

7270
@staticmethod

src/backend/tile_handler.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,6 @@ def findTilesByNeighborhood(self, neighborhood: int) -> List[NeighborhoodEntry]:
115115
if neighborhood < 0 or neighborhood >= 2**8:
116116
raise ValueError("only use 8 bit neighbourhood to find tiles by neighborhood")
117117
return self.neighborhood_map[neighborhood]
118+
119+
def reset(self):
120+
self._init()

src/config/app_state.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ def setImagePath(cls, image_path):
4343
cls.instance().rule_manager.loadRules(Path(image_path).stem)
4444
cls.instance().signal_emitter.application_status_signal.emit(ApplicationStatusEnum.IMAGE_LOADED, "")
4545

46+
@classmethod
47+
def reset(cls):
48+
# do not call _init here, don't overwrite the signal emitter, reset manually
49+
cls.instance().rule_manager: RuleManager = RuleManager()
50+
cls.instance().main_image_path: Optional[str] = None
51+
cls.instance().signal_emitter.application_status_signal.emit(ApplicationStatusEnum.RESET_APP, "")
52+
4653
@classmethod
4754
def setStatus(cls, status_type: ApplicationStatusEnum, message: str):
4855
if status_type == ApplicationStatusEnum.IMAGE_LOADED:

src/main_window.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
from src.widgets.widget_image_selector import ImageSelectorWidget
1010
from src.config.app_state import AppState
1111
from src.signals.signal_emitter import ApplicationStatusEnum
12+
from src.backend.tile_handler import TileHandler
13+
import logging
14+
15+
logger = logging.getLogger(__name__)
1216

1317

1418
class MainWindow(QMainWindow):
@@ -63,8 +67,13 @@ def showAbout(self):
6367
QMessageBox.about(self, 'About', 'This is a PyQt6 menu example.')
6468

6569
def statusUpdateReceived(self, status_type: ApplicationStatusEnum, message: str):
70+
logger.debug(f"Status update received: {status_type}, {message}")
6671
if status_type == ApplicationStatusEnum.IMAGE_LOADED:
6772
self.mapper_generator.setEnabled(True)
6873
self.mapper_generator.widget().rulesLoaded()
6974
# TODO set status dockwidget "Successfully loaded image"
75+
elif status_type == ApplicationStatusEnum.RESET_APP:
76+
self.mapper_generator.widget().reset()
77+
self.central_widget.reset()
78+
TileHandler.instance().reset()
7079
pass

src/signals/signal_emitter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class ConfigurationClickedEmitter(QObject):
99

1010
class ApplicationStatusEnum(Enum):
1111
IMAGE_LOADED = "ImageLoaded"
12+
RESET_APP = "ResetApp"
1213
WARNING = "Warning"
1314
INFO = "Info"
1415

src/widgets/widget_image_selector.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,15 @@ def select_image(self):
3737
if selected_files:
3838
image_path = selected_files[0]
3939
pixmap = QPixmap(image_path)
40+
if AppState.imagePath():
41+
AppState.reset() # reset app before loading new, calls self.reset somewhere
4042
if not pixmap.isNull():
4143
self.image_label.setPixmap(pixmap)
4244
AppState.setImagePath(image_path)
4345
# else:
4446
# self.image_label.setText("Invalid image file")
47+
48+
def reset(self):
49+
self.layout().removeWidget(self.image_label)
50+
self.image_label = TileClicker(self)
51+
self.layout().addWidget(self.image_label)

src/widgets/widget_mapper_generator.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from PyQt6.QtGui import QPixmap, QRegularExpressionValidator
66
from PyQt6.QtCore import QRegularExpression
77

8-
from src.config.app_state import AppState
8+
from src.config.app_state import AppState, ApplicationStatusEnum
99
from src.dialogs.dialog_check_map import CheckMapDialog
1010
from src.config.config_manager import ConfigManager
1111

@@ -87,8 +87,13 @@ def __init__(self, parent=None):
8787
self.new_mapper_line_edit.setMaxLength(128) # limit number of characters
8888

8989
def startRuleGeneration(self):
90-
rule_name = self.new_mapper_line_edit.text()
91-
if not AppState.imagePath() or not len(rule_name):
90+
if self.radio_buttons[0].isChecked():
91+
rule_name = self.new_mapper_line_edit.text()
92+
else:
93+
rule_name = self.existing_mapper_combobox.currentText()
94+
95+
if not AppState.imagePath() or not rule_name or not len(rule_name):
96+
AppState.setStatus(ApplicationStatusEnum.WARNING, "You can't generate without a rule name")
9297
return
9398
cmd = CheckMapDialog(self, title=f"Do you want to save your mapping rule '{rule_name}'?", cancel=True)
9499
ret = cmd.exec()
@@ -102,11 +107,20 @@ def checkMappingRules(self):
102107
cmd.exec()
103108

104109
def mappingRuleNameChanged(self):
105-
rule_name = self.new_mapper_line_edit.text()
106-
if not rule_name or len(rule_name) == 0:
107-
self.generate_button.setDisabled(True)
110+
self._updateGenerateButton()
111+
112+
def _updateGenerateButton(self):
113+
if self.radio_buttons[0].isChecked():
114+
rule_name = self.new_mapper_line_edit.text()
115+
if not rule_name or len(rule_name) == 0:
116+
self.generate_button.setDisabled(True)
117+
else:
118+
self.generate_button.setEnabled(True)
108119
else:
109-
self.generate_button.setEnabled(True)
120+
if not self.existing_mapper_combobox.count():
121+
self.generate_button.setDisabled(True)
122+
else:
123+
self.generate_button.setEnabled(True)
110124

111125
def ruleNameToggle(self):
112126
if self.radio_buttons[0].isChecked():
@@ -115,6 +129,7 @@ def ruleNameToggle(self):
115129
elif self.radio_buttons[1].isChecked():
116130
self.new_mapper.hide()
117131
self.existing_mapper.show()
132+
self._updateGenerateButton()
118133

119134
def startDDNetCheck(self):
120135
# TODO
@@ -137,5 +152,12 @@ def rulesLoaded(self):
137152
self.radio_buttons[1].setEnabled(True)
138153
else: # disable combo box
139154
if self.radio_buttons[1].isChecked():
140-
self.ruleNameToggle() # only new is available
155+
self.radio_buttons[0].click()
141156
self.radio_buttons[1].setDisabled(True)
157+
self._updateGenerateButton()
158+
159+
def reset(self):
160+
if self.radio_buttons[1].isChecked():
161+
self.ruleNameToggle()
162+
self.new_mapper_line_edit.setText("")
163+
self.existing_mapper_combobox.clear()

0 commit comments

Comments
 (0)