OnExitCallbackManager.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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 all registered upon-exit checks
  9. # that need to be performed when the application tries to exit.
  10. # For example, show a confirmation dialog when there is USB printing in progress.
  11. # All callbacks will be called in the order of when they were registered.
  12. # If all callbacks "pass", for example:
  13. # if the user clicks "yes" on the exit confirmation dialog
  14. # and nothing else is blocking the exit, then the application will quit.
  15. #
  16. class OnExitCallbackManager:
  17. def __init__(self, application: "CuraApplication") -> None:
  18. self._application = application
  19. self._on_exit_callback_list = list() # type: List[Callable]
  20. self._current_callback_idx = 0
  21. self._is_all_checks_passed = False
  22. def addCallback(self, callback: Callable) -> None:
  23. self._on_exit_callback_list.append(callback)
  24. Logger.log("d", "on-app-exit callback [%s] added.", callback)
  25. # Reset the current state so the next time it will call all the callbacks again.
  26. def resetCurrentState(self) -> None:
  27. self._current_callback_idx = 0
  28. self._is_all_checks_passed = False
  29. def getIsAllChecksPassed(self) -> bool:
  30. return self._is_all_checks_passed
  31. # Trigger the next callback if there is one.
  32. # If not, all callbacks have "passed",
  33. # which means we should not prevent the application from quitting,
  34. # and we call the application to actually quit.
  35. def triggerNextCallback(self) -> None:
  36. # Get the next callback and schedule it
  37. this_callback = None
  38. if self._current_callback_idx < len(self._on_exit_callback_list):
  39. this_callback = self._on_exit_callback_list[self._current_callback_idx]
  40. self._current_callback_idx += 1
  41. if this_callback is not None:
  42. Logger.log("d", "Scheduled the next on-app-exit callback [%s]", this_callback)
  43. self._application.callLater(this_callback)
  44. else:
  45. Logger.log("d", "No more on-app-exit callbacks to process. Tell the app to exit.")
  46. self._is_all_checks_passed = True
  47. # Tell the application to exit
  48. self._application.callLater(self._application.closeApplication)
  49. # Callback function which an on-exit callback calls when it finishes.
  50. # It provides a "should_proceed" flag indicating whether the check has "passed",
  51. # or whether quitting the application should be blocked.
  52. # If the last on-exit callback doesn't block quitting, it will call the next
  53. # registered on-exit callback if one is available.
  54. def onCurrentCallbackFinished(self, should_proceed: bool = True) -> None:
  55. if not should_proceed:
  56. Logger.log("d", "on-app-exit callback finished and we should not proceed.")
  57. # Reset the state
  58. self.resetCurrentState()
  59. return
  60. self.triggerNextCallback()