OnExitCallbackManager.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. # Copyright (c) 2018 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from typing import TYPE_CHECKING, Callable, List
  4. from UM.Logger import Logger
  5. if TYPE_CHECKING:
  6. from cura.CuraApplication import CuraApplication
  7. #
  8. # This class manages a all registered upon-exit checks that need to be perform when the application tries to exit.
  9. # For example, to show a confirmation dialog when there is USB printing in progress, etc. All callbacks will be called
  10. # in the order of when they got registered. If all callbacks "passes", that is, for example, if the user clicks "yes"
  11. # on the exit confirmation dialog or nothing that's blocking the exit, then the application will quit after that.
  12. #
  13. class OnExitCallbackManager:
  14. def __init__(self, application: "CuraApplication") -> None:
  15. self._application = application
  16. self._on_exit_callback_list = list() # type: List[Callable]
  17. self._current_callback_idx = 0
  18. self._is_all_checks_passed = False
  19. def addCallback(self, callback: Callable) -> None:
  20. self._on_exit_callback_list.append(callback)
  21. Logger.log("d", "on-app-exit callback [%s] added.", callback)
  22. # Reset the current state so the next time it will call all the callbacks again.
  23. def resetCurrentState(self) -> None:
  24. self._current_callback_idx = 0
  25. self._is_all_checks_passed = False
  26. def getIsAllChecksPassed(self) -> bool:
  27. return self._is_all_checks_passed
  28. # Trigger the next callback if available. If not, it means that all callbacks have "passed", which means we should
  29. # not block the application to quit, and it will call the application to actually quit.
  30. def triggerNextCallback(self) -> None:
  31. # Get the next callback and schedule that if
  32. this_callback = None
  33. if self._current_callback_idx < len(self._on_exit_callback_list):
  34. this_callback = self._on_exit_callback_list[self._current_callback_idx]
  35. self._current_callback_idx += 1
  36. if this_callback is not None:
  37. Logger.log("d", "Scheduled the next on-app-exit callback [%s]", this_callback)
  38. self._application.callLater(this_callback)
  39. else:
  40. Logger.log("d", "No more on-app-exit callbacks to process. Tell the app to exit.")
  41. self._is_all_checks_passed = True
  42. # Tell the application to exit
  43. self._application.callLater(self._application.closeApplication)
  44. # This is the callback function which an on-exit callback should call when it finishes, it should provide the
  45. # "should_proceed" flag indicating whether this check has "passed", or in other words, whether quitting the
  46. # application should be blocked. If the last on-exit callback doesn't block the quitting, it will call the next
  47. # registered on-exit callback if available.
  48. def onCurrentCallbackFinished(self, should_proceed: bool = True) -> None:
  49. if not should_proceed:
  50. Logger.log("d", "on-app-exit callback finished and we should not proceed.")
  51. # Reset the state
  52. self.resetCurrentState()
  53. return
  54. self.triggerNextCallback()