docs: def on_close_clicked(self, event, state_machine_m, result, force=False):
          """Triggered when the close button of a state machine tab is clicked
  
          Closes state machine if it is saved. Otherwise gives the user the option to 'Close without Saving' or to 'Cancel
          the Close Operation'
  
          :param state_machine_m: The selected state machine model.
          """
          from rafcon.core.singleton import state_machine_execution_engine, state_machine_manager
          force = True if event is not None and hasattr(event, 'state') \
                          and event.get_state() & Gdk.ModifierType.SHIFT_MASK \
                          and event.get_state() & Gdk.ModifierType.CONTROL_MASK else force
  
          def remove_state_machine_m():
              state_machine_id = state_machine_m.state_machine.state_machine_id
              if state_machine_id in self.model.state_machine_manager.state_machines:
                  self.model.state_machine_manager.remove_state_machine(state_machine_id)
  
          def push_sm_running_dialog():
  
              message_string = "The state machine is still running. Are you sure you want to close?"
              dialog = RAFCONButtonDialog(message_string, ["Stop and close", "Cancel"],
                                          message_type=Gtk.MessageType.QUESTION, parent=self.get_root_window())
              response_id = dialog.run()
              dialog.destroy()
              if response_id == 1:
                  logger.debug("State machine execution is being stopped")
                  state_machine_execution_engine.stop()
                  state_machine_execution_engine.join()
                  # wait for gui is needed; otherwise the signals related to the execution engine cannot
                  # be processed properly by the state machine under destruction
                  rafcon.gui.utils.wait_for_gui()
                  remove_state_machine_m()
                  return True
              elif response_id == 2:
                  logger.debug("State machine execution will keep running")
              return False
  
          def push_sm_dirty_dialog():
  
              sm_id = state_machine_m.state_machine.state_machine_id
              root_state_name = state_machine_m.root_state.state.name
              message_string = "There are unsaved changes in the state machine '{0}' with id {1}. Do you want to close " \
                               "the state machine anyway?".format(root_state_name, sm_id)
              dialog = RAFCONButtonDialog(message_string, ["Close without saving", "Cancel"],
                                          message_type=Gtk.MessageType.QUESTION, parent=self.get_root_window())
              response_id = dialog.run()
              dialog.destroy()
              if response_id == 1:  # Close without saving pressed
                  remove_state_machine_m()
                  return True
              else:
                  logger.debug("Closing of state machine canceled")
              return False
  
          # sm running
          if not state_machine_execution_engine.finished_or_stopped() and \
                  state_machine_manager.active_state_machine_id == state_machine_m.state_machine.state_machine_id:
              return push_sm_running_dialog()
          # close is forced -> sm not saved
          elif force:
              remove_state_machine_m()
              return True
          # sm dirty -> save sm request dialog
          elif state_machine_m.state_machine.marked_dirty:
              return push_sm_dirty_dialog()
          else:
              remove_state_machine_m()
              return True