// ********************************************************
// An event fired by the application when it is initialized
// ********************************************************
event Qualibus.Initialize()
{
  QappCore.initializeQualibusWeb()
  Qualibus.initializeQualibusWebGlobalVariables()
  Qualibus.initializeQappCoreGlobalVariables()
  Qualibus.handlePendingCommandFromCookiesIfNeeded()
   
  Qualibus.QualibusWebVersion = "NES 0.11"
   
  DevTools.temporaryWorkaround("JS customization of Client.IdfFieldValue.prototype.handleBlobUpload done in customf.js, IT MUST BE KEPT IN SYNC WITH NEWER INDE VERSIONS ", "25.5", "as new inde is out review the method to be sure it 
        is still like before", "using D&D to insert more files at once in docmenti should work")
  DevTools.temporaryWorkaround("Patch P001295 in patchInde", "25.5", "Inde patch to render command set in nested subform ", "Check if modelli eventi opzioni has aggiungi button in subform")
  DevTools.temporaryWorkaround("Patch P001296 in patchInde", "25.5", "Inde patch to make F5 not breaking the UI", "open clifor detail, press F5: the UI should not break")
  DevTools.temporaryWorkaround("Patch P001298 in patchInde", "25.5", "Inde patch to make ellipsis runtime button appear correctly in the last collumn", "remove the IJLib.dll file from the "BIN" folder of QualibusWeb custom folder 
        and check if in doc collegati of modello evento the ellipsis stay on the last column")
  DevTools.temporaryWorkaround("Patch P001282 in patchInde", "25.5", "load requirements fails in custom component (multitypefield component in our case)", "open anaclifor: custom data shows well without desktop.js loading eternally"
    )
  DevTools.temporaryWorkaround("Patch P001305 in patchInde", "25.5", "typing on a field linked to imdb search makes focus go randomly at the beginning", "open clifor serach: type somethign fast and see that all is well writte: NOTE 
        if we remove IMDB searches likely we won't see this problem anymore so it is difficult to mark this patch as "done" in future")
   
  DevTools.temporaryWorkaround("On 2 methods: MainModuleUILogic.createSubforms and MainModuleUILogic.addCommonSubforms", "25.5", "className used on moduleType.shouldTabBeVisible fixed with a workaround because of INDE bug of JAVA 
        that puts the name of the component in the IDForm.className() procedure", ...)
  DevTools.temporaryWorkaround("PATCH: P001311 - NPQ06862 - 000169-2026 ", "25.5", "lateral menu flickering after login, because menu icons are rendered later", ...)
   
}


// ──────────────────────────────────

// **********************************************************************
// An event fired by the application when a command is passed via the URL
// **********************************************************************
event Qualibus.OnCommand(
  string Command // It is a string containing the value of the URL parameter named CMD
)
{
  Qualibus.QWCommandHandler.HandleCommand(Command)
}


// ──────────────────────────────────

// *****************************************************************************
// An event fired by the application when it receives a message from the browser
// *****************************************************************************
event Qualibus.OnBrowserMessage(
  string Message     // This indicates the name of the message received from the browser.
  XMLNode Node       // This is the XML node received from the browser. It contains all the information collected by the client that will be managed by the system
  inout boolean Skip // A boolean output parameter. If set to True, it makes sure the framework does not manage this message
)
{
  if (Message == "start")
  {
    ExecuteCustomizationJs.enabled = true
  }
   
  // special code to check whether logoff was pressed to unlock calendar impossibility to close
  boolean logOffWasPressed = IndeEventsImplementationHelper.OnBrowserMessageLogOffWasPressed(Message, Node)
  if (logOffWasPressed)
  {
    Calendar.sendMessage("LOGOFF_CALLED", ...)
  }
}


// ──────────────────────────────────

// *************************************************************************************************************************************************
// Event raised to the application or to a component when something, an application or component, has sent a message using the SendAppMessage method
// *************************************************************************************************************************************************
event Qualibus.OnAppMessage(
  string Message   // Name of the message
  object Parameter // An object-type parameter that contains the information about the message sent. This parameter is the one provided to the SendAppMessage method
)
{
  if (Message == "AddCommandSet")
  {
    IDCommand idc = cast(Parameter)
    Qualibus.addCommandSet(idc)
  }
  if (Message == "DIAGRAM_JSON")
  {
    IDArray ida = cast(Parameter)
    string jsonDiagram = ida.getValue(0)
     
    Qualibus.ModelloEventoDetailVariableForSavingDiagram.sendMessage("STORE_JSON", null, jsonDiagram, ...)
  }
   
  if (Message == "OPEN_DETAIL_FORM")
  {
    if (Parameter == null)
    {
      Qualibus.DTTLogMessage("Can't open form if parameter is null", ..., DTTError)
      return 
    }
     
    MainModule mm = cast(Parameter)
    DetailFormOpener.openDetailFormOfMainModule(mm)
  }
}


// ──────────────────────────────────

// ***************************************************************
// An event fired by the application after the system was accessed
// ***************************************************************
event Qualibus.AfterLogin()
{
  if (X.inServerSession())
    return 
   
  if ((QappCore.LoggedInFromQmobile and UIBusinessLogic.StartEventoWizardAfterLogin) or UIBusinessLogic.StartEventoWizardAfterLogin)
  {
    ECFWFirstStep.showForm(QappCore.Loggeduser, UIBusinessLogic.URLTOKEN)
  }
  else 
  {
    boolean proceedWithAutoLogin = false
    Qualibus.displayOneWayUpgraderProgressFormIfNeeded(proceedWithAutoLogin)
     
    if (proceedWithAutoLogin)
    {
      boolean menuAlreadyBuilt = Qualibus.MenuManager != null
      if (menuAlreadyBuilt)
      {
         Qualibus.DTTLogMessage("AfterLogin: menu already built, skipping prepareCalendarAndMenu", ..., DTTInfo)
      }
      else 
         Qualibus.prepareCalendarAndMenu()
       
      // open pending module (if any) AFTER menu/calendar so the form stays on top
      Qualibus.QWCommandHandler.openModuleIfPending()
    }
  }
   
   
}


// ──────────────────────────────────

// *****************************************************************************
// An event fired by the application immediately before closing the user session
// *****************************************************************************
event Qualibus.Terminate()
{
   
  // in case user closes the browser withotu login and session closes automatically we clear the id user cookie
  CookieHelper.clearLastLoggedUsrIdCookie()
}


// ──────────────────────────────────

// ****************************************************************
// An event fired by the application when the user performs a login
// ****************************************************************
event Qualibus.OnLogin(
  inout string UserName   // It is a string containing the username entered by the user to access the system.
  inout string Password   // It is a string containing the password entered by the user to access the system.
  inout boolean DataValid // If set to True it informs the framework that the data entered by the user is valid: setting it to False indicates that the username and password are incorrect
)
{
  if (UIBusinessLogic.StartEventoWizardAfterLogin)
  {
    // QappCore.OnLogin handles all real login checks (credentials, ATTIVO flag, privileges, DB version).
    // However, QappCore.doLogin never sets DataValid = false on failure — it only sets errorMessage.
    // So we use Loggeduser.IDUTENTE > 0 as the reliable success indicator: it is only populated
    // when doLogin completes successfully. If not, we force DataValid = false to prevent the
    // framework from letting the user in despite a failed login.
    boolean QappCoreOnLoginLoggedInAUser = QappCore.Loggeduser.IDUTENTE > 0
    if (DataValid and QappCoreOnLoginLoggedInAUser)
    {
      Qualibus.userRole = Administrator
    }
    else 
    {
      DataValid = false
    }
  }
}


// ──────────────────────────────────

// ****************************************************************
// Event raised by the command set when it is expanded or collapsed
// ****************************************************************
event Qualibus.MainMenu.OnChangeExpand(
  boolean Expanded     // A boolean value that indicates whether the command set was opened (True) or closed (False).
  inout boolean Cancel // A boolean output parameter. When set to True, the open/close operation is canceled.
)
{
   
  // avoid that the main menu can be vertically collapsed
  if (Expanded = false)
  {
    Cancel = true
  }
}


// ──────────────────────────────────

// **********************************************************************
// Allows the visual properties of individual panel cells to be adjusted.
// **********************************************************************
event Qualibus.GlobalPanelDynamicProperties(
  IDPanel Panel // Object that fires this event
)
{
  GlobalPanelEventsHandler.OnDynamicPropertiesRowHiding(Panel, ...)
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event Qualibus.GlobalLoad(
  IDForm Form // Object that fires this event
)
{
  FormToolAutomation.setupPanelsCommands(Form)
}


// ──────────────────────────────────

// **************************************************************************************
// Event raised to the form when it is activated, meaning when it is brought to the front
// **************************************************************************************
event Qualibus.GlobalActivate(
  IDForm Form // Object that fires this event
)
{
}


// ──────────────────────────────────

// *******************************************************************
// An event fired by the application when any command is used by users
// *******************************************************************
event Qualibus.GlobalCmdSetCommand(
  IDCommand CommandSet // It's an IDCommand type instance representing the command set that contains the command used by users.
  IDCommand Command    // It's an IDCommand type instance representing the command used by users.
  inout boolean Cancel // If set to True it indicates to the system that it must not notify the specific events of the command sets if they are implemented.
)
{
  Qualibus.MainMenuHandler.handleClickOnMenuCommand(Command)
   
  UIBusinessLogic.ReferenceTypeMenuController.globalCommandSetCmdHandler(Command)
   
   
}


// ──────────────────────────────────

// *****************************************************
// Global event corresponding to the panel Before Insert
// *****************************************************
event Qualibus.GlobalBeforeInsert(
  IDPanel Panel        // Panel that generated this event
  inout boolean Cancel // If set to True, the data for this row is not inserted. The saving step for other rows proceeds as normal.
)
{
}


// ──────────────────────────────────

// ****************************************************
// Event raised by the panel when a field is activated.
// ****************************************************
event Qualibus.GlobalPanelActivateField(
  IDPanel Panel        // Object that fires this event
  int FieldIndex       // An integer representing the panel field that has been activated. It should be compared with the Me property of the panel field.
  inout boolean Cancel // This can be set to True to cancel activation by any activation object associated with the panel field.
)
{
}


// ──────────────────────────────────

// **********************************************
// Raised by the panel when the user clicks on it
// **********************************************
event Qualibus.GlobalPanelMouseClick(
  IDPanel Panel        // Object that fires this event
  int:mouseButtons Button // Specifies which mouse button has been pressed. Refer also to the MouseButtons value list
  int X                // X position in pixels relative to the panel in which the mouse was clicked
  int Y                // Y position in pixels relative to the panel in which the mouse was clicked
  int XB               // X position in pixels relative to the browser in which the mouse was clicked
  int YB               // Y position in pixels relative to the browser in which the mouse was clicked
  int Column           // Index of the field that was clicked (-1 if the click occurred outside the fields)
  int Row              // Row clicked, from 0 to VisibleRows -1. This is -1 if the click occurred outside the fields or on the caption of the column or field
  inout boolean Cancel // Can be set to True to prevent the default action associated with the click from being run, such as execution of the field activation object.
)
{
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Calendar.loadEventsOnScheduler()
{
  IDCollection events of SchedulerEvent = this.QualibusSchedulerController.getEvents(...)
  for each SchedulerEvent se in events
  {
    Scheduler.sendMessage(addEvent, se, ...)
  }
   
}


// ──────────────────────────────────

// *******************************************************************************************************
// this procedure prepares the Qualibus Scheduler controller object to initialize the Devextreme Scheduler
// 
// Initially we handle only the logged user
// *******************************************************************************************************
private void Calendar.configureScheduler()
{
  date time from = dateAdd(Month, -1, today())
  date time to = dateAdd(Month, 1, today())
  IDCollection initialUsers of Utente = new()
  initialUsers.add(QappCore.Loggeduser)
  this.QualibusSchedulerController = QualibusSchedulerController.create(initialUsers, from, to)
  SchedulerConfiguration sc = this.QualibusSchedulerController.getConfiguration()
  Scheduler.sendMessage(configuration, sc, ...)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Calendar.UserSelection()
{
  IDCollection userResultContainer of Utente = new()
  this.setObjectTag("userSelectionResult", userResultContainer)
  EmployeesSelection.showForm(userResultContainer)
}


// ──────────────────────────────────

// *****************************************************************************************************************************************************************************************************************************
// this procedure updates the QualibusSchedulerController with the new resources and updates also the dxSCehduler controller in the Devex component, asking to update the dxScheduler with the new resources choosen by the user
// *****************************************************************************************************************************************************************************************************************************
private void Calendar.updateSchedulerResources()
{
  IDCollection userResultContainer of Utente = this.getObjectTag("userSelectionResult")
  if (userResultContainer.count() > 0)
  {
    // set new resources and reinit calendar with new res and new events
     
    IDCollection coll of SchedulerEvent = this.QualibusSchedulerController.getEvents(...)
    for each SchedulerEvent se in coll
    {
      Scheduler.sendMessage(deleteEvent, se, ...)
    }
    this.QualibusSchedulerController.updateConfigurationsForNewUsers(userResultContainer)
    SchedulerConfiguration sc = new()
    IDArray resources = this.QualibusSchedulerController.computeResources(userResultContainer)
    sc.Resources = resources
    IDMap request = new()
    request.setValue("name", resources)
    request.setObject("value", resources)
    MessageData md = MessageData.create(request)
    Scheduler.sendMessage(changeOption, md, ...)
    this.loadEventsOnScheduler()
  }
}


// ──────────────────────────────────

// *********************************************************************************
// Event raised by the form object in web applications when a modal window is closed
// *********************************************************************************
event Calendar.EndModal(
  int LookupForm       // An integer that identifies the modal form that was just closed, using the Me function of the form object to make the comparison.
  boolean Result       // True if the user confirmed the choice, closing the model form using the confirmation button on the title bar; otherwise False. The form can also be closed using the form object's Close procedure.
  inout boolean Cancel // If set to True, any subsequent automatic processing will be canceled. In this case, the framework will not attempt to automatically transfer the data from the modal form to the calling form.
)
{
  if (Result and LookupForm == EmployeesSelection.me())
  {
    this.updateSchedulerResources()
  }
}


// ──────────────────────────────────

// ******************************************
// Event fired to the form when it is resized
// ******************************************
event Calendar.OnResize(
  inout int NewWidth   // An integer representing the new width of the form measured in pixels.
  inout int NewHeight  // An integer representing the new height of the form measured in pixels.
  inout boolean Cancel // If set to the True, it cancels resizing of the form, panels, and fields, and other visual objects are not subject to layout changes. It has no effect on the size of the browser window, which will follow t...
)
{
}


// ──────────────────────────────────

// ********************************************
// Event raised by the form before it is closed
// ********************************************
event Calendar.Unload(
  inout int Cancel // If set to True, closure of the form is canceled.
  boolean Confirm  // Represents the user's selection for closing modal forms. True if the user confirms their choice, otherwise False.
)
{
  Cancel = !(this.AllowClosure)
}


// ──────────────────────────────────

// ************************************************************************
// Event raised when a form sends a message using the SendMessage procedure
// ************************************************************************
event Calendar.OnSendMessage(
  string Message // Indicates the name of the message
  IDForm Sender  // Identifies the form that sent the message. IDForm type object.
  IDDocument Doc // Optional. Document associated with the message.
  string Par1    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par2    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par3    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par4    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
)
{
   
  // when logoff is called we allow to close the form
  if (Message == "LOGOFF_CALLED")
  {
    this.AllowClosure = true
  }
}


// ──────────────────────────────────

// **************************************************************************************
// Event raised to the form when it is activated, meaning when it is brought to the front
// **************************************************************************************
event Calendar.Activate()
{
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void CliforDefaultPrintPOCReportForm.PrintReport(
  MainModule mainModule // Write a comment for this parameter or press backspace to delete this comment
)
{
  string logoFileName = TabParametri.extractPrintLogoToImageFolder("logo")
  ReportBook.LabelLogo.setImage(logoFileName)
  mainModule.loadCollectionFromDB(mainModule.Promemoria, ...)
  Clifor c = (Clifor)mainModule
//  c.loaded = true
   
  ReportBook.MainReport.setDocument(c)
  Qualibus.DTTLogMessage(mainModule.Promemoria.count(), 121212, ...)
  ReportBook.SubReportPromemoria.setCollection(mainModule.Promemoria)
  ReportBook.printDestination = SCREEN
  ReportBook.print(1, -1)
   
  if (ReportBook.numberofPagesConfirmed())
  {
    boolean bookHasMorePages = ReportBook.numberofPages() > 1
    ReportBook.setCommandEnabled(Navigate, bookHasMorePages)
  }
   
}


// ──────────────────────────────────

// ************************************************************
// Event fired by a page when it is being prepared for printing
// ************************************************************
event CliforDefaultPrintPOCReportForm.ReportBook.ReportPage.OnBeforeFormatting()
{
  if (ReportBook.numberofPagesConfirmed())
  {
    ReportBook.MainReport.pagecount.text = formatMessage("Pagina |1 di |2", ReportBook.pageNumber(), ReportBook.numberofPages(), ...)
  }
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event CliforDefaultPrintPOCReportForm.Load()
{
  ReportBook.collapsable = false
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event CliforList.Load()
{
  Search.Searchstring = ""
  Clifor.collapsable = false
  Clifor.collapsed = false
   
   
  if (Qualibus.GridSettingsTemp != "")
  {
    Clifor.setPanelConfiguration(Qualibus.GridSettingsTemp)
  }
//  Clifor.listQBE = Row
  Clifor.caption = ""
  boolean userCanSeeOpzioniClifor = QappCore.Loggeduser.hasSpecificPrivilege(TabelleClientiFornitori, Execute)
  OptionsIndividual.setCommandVisible(Options.getIndex(), userCanSeeOpzioniClifor)
   
  QuickViewclifordetail.visible = false
  QuickViewclifordetail.collapsable = false
   
}


// ──────────────────────────────────

// *****************************************************
// Raised by the panel when the user double clicks on it
// *****************************************************
event CliforList.Clifor.OnMouseDoubleClick(
  int:mouseButtons Button // Specifies which mouse button has been pressed. Refer also to the MouseButtons value list
  int X                // X position in pixels relative to the panel in which the mouse was clicked
  int Y                // Y position in pixels relative to the panel in which the mouse was clicked
  int XB               // X position in pixels relative to the browser in which the mouse was clicked
  int YB               // Y position in pixels relative to the browser in which the mouse was clicked
  int Column           // Index of the field that was clicked (-1 if the click occurred outside the fields)
  int Row              // Row clicked, from 0 to VisibleRows -1. This is -1 if the click occurred outside the fields or on the caption of the column or field
  inout boolean Cancel // Can be set to True to prevent the default action associated with the click from being run, such as execution of the field activation object.
)
{
  if (Row > 0 and Column != -1)
  {
    this.edit()
  }
}


// ──────────────────────────────────

// ***************************************************************************
// Event raised by the panel when the user rearranges the columns in the list.
// ***************************************************************************
event CliforList.Clifor.OnReorderColumn(
  int SourceField // An integer representing the panel field that has been dragged & dropped. It should be compared with the Me property of the panel field.
  int TargetField // An integer representing the target field of the drag & drop operation. It should be compared with the Me property of the panel field. The dragged field is inserted just before the target field taking the drop.
)
{
  // 
   
  Qualibus.GridSettingsTemp = Clifor.getPanelConfiguration()
   
   
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************************
// Event raised by the panel when a field is activated.
// ****************************************************
event CliforList.Clifor.OnActivateField(
  int FieldIndex       // An integer representing the panel field that has been activated. It should be compared with the Me property of the panel field.
  inout boolean Cancel // This can be set to True to cancel activation by any activation object associated with the panel field.
)
{
}


// ──────────────────────────────────

// **********************************************
// Raised by the panel when the user clicks on it
// **********************************************
event CliforList.Clifor.OnMouseClick(
  int:mouseButtons Button // Specifies which mouse button has been pressed. Refer also to the MouseButtons value list
  int X                // X position in pixels relative to the panel in which the mouse was clicked
  int Y                // Y position in pixels relative to the panel in which the mouse was clicked
  int XB               // X position in pixels relative to the browser in which the mouse was clicked
  int YB               // Y position in pixels relative to the browser in which the mouse was clicked
  int Column           // Index of the field that was clicked (-1 if the click occurred outside the fields)
  int Row              // Row clicked, from 0 to VisibleRows -1. This is -1 if the click occurred outside the fields or on the caption of the column or field
  inout boolean Cancel // Can be set to True to prevent the default action associated with the click from being run, such as execution of the field activation object.
)
{
  if (Button == Left or Button == Right)
  {
    if (Row != -1)
    {
      this.Quickview()
    }
    else 
    {
      this.QuickViewClose()
    }
  }
}


// ──────────────────────────────────

// ************************************************************************
// Event raised when a form sends a message using the SendMessage procedure
// ************************************************************************
event CliforList.OnSendMessage(
  string Message // Indicates the name of the message
  IDForm Sender  // Identifies the form that sent the message. IDForm type object.
  IDDocument Doc // Optional. Document associated with the message.
  string Par1    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par2    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par3    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par4    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
)
{
  if (Message == "BringToFront")
  {
    this.bringToFront()
  }
   
}


// ──────────────────────────────────



// ──────────────────────────────────

// **********************************************************************
// Allows the visual properties of individual panel cells to be adjusted.
// **********************************************************************
event CliforList.QuickViewclifordetail.OnDynamicProperties()
{
  if (QuickViewclifordetail.STATOCONTO == Chiuso)
  {
    QuickViewclifordetail.STATOCONTO.textColor = RGBColor(178, 34, 34, ...)
  }
  if (QuickViewclifordetail.STATOCONTO == Potenziale)
  {
    QuickViewclifordetail.STATOCONTO.textColor = RGBColor(255, 127, 0, ...)
  }
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void CliforList.edit()
{
  if (Clifor.IDCONTOGCFANAGRAFICA > 0)
  {
    // to show the errors on the cliforDetail form
    Clifor selectedClifor = Clifor.getFromDB(Clifor.IDCONTOGCFANAGRAFICA, ...)
    if (selectedClifor)
    {
       
      // Create an instance of Detail form
      CliforDetail cd = new()
      cd.formShow(selectedClifor, this)
    }
  }
   
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void CliforList.New()
{
  // Important: to display commandset on any form we must have some caption so while creating a new customer we pass ragione sociale as " "(Space) so that it will be set as caption of clifor detail form, otherwise indietro command
  // will not be visible
   
   
  RegistryTypeSelection.showForm(ClientiFornitori)
   
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void CliforList.OpenOptionsForm()
{
  MainPageFormInstanceFactory.AssegnaRuoli(TabelleClientiFornitori)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void CliforList.Quickview()
{
  int idClifor = Clifor.IDCONTOGCFANAGRAFICA
  if (idClifor > 0)
  {
    Clifor c = Clifor.getFromDB(idClifor, quickLoad)
    QuickViewclifordetail.setDocument(c, ...)
    QuickViewclifordetail.visible = true
    QuickViewclifordetail.caption = c.RAGIONESOCIALE
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void CliforList.QuickViewClose()
{
  QuickViewclifordetail.visible = false
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void CliforDetail.formShow(
  Clifor clifor // Write a comment for this parameter or press backspace to delete this comment
  IDForm caller // 
)
{
  this.Clifor = clifor
  this.CliforMainModuleFormHelper = MainModuleFormHelper.create(clifor, CommonMainModuleTabbedView.IDForm(), this)
  this.setObjectTag("caller", caller)
  this.show(...)
  this.CliforMainModuleFormHelper.updateCaptionInMainForm("")
  this.CliforMainModuleFormHelper.initializeAllTabbedViewSubForms()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void CliforDetail.Back()
{
  DevTools.ToBeReviewed("to be made common!")
   
  Clifor clifor = this.Clifor
  boolean docIsModified = clifor.isModified(...)
  boolean formShouldBeClosed = true
  boolean rollbackChanges = false
   
  if (docIsModified)
  {
    int i = Qualibus.messageConfirmEx("Ci sono modifiche non ancora salvate, vuoi davvero uscire?", "Sì;No")
    if (i == null)
      return 
     
    if (i == 1)
    {
      formShouldBeClosed = true
      rollbackChanges = true
    }
    else 
    {
      formShouldBeClosed = false
    }
     
  }
   
  if (rollbackChanges)
  {
    clifor.restoreOriginal()
  }
   
  if (formShouldBeClosed)
  {
    this.close(true)
    IDForm caller = this.getObjectTag("caller")
    caller.bringToFront()
    SearchFilterIMDBInteractions.initializePanelSearchQueriesRuntimeFilters(..., ClientiFornitori)
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void CliforDetail.insert()
{
  Clifor c = null
  if (c)
  {
    IDCollection tags of GCFCARATTERIZZAZIONI = c.GCFCARATTERIZZAZIONI
    GCFCARATTERIZZAZIONI tag = GCFCARATTERIZZAZIONI.create(c.IDCONTO)
    tag.inserted = true
    tags.add(tag)
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void CliforDetail.Stampa()
{
  Clifor c = this.Clifor
  if (c)
  {
    CliforDefaultPrintPOCReportForm.PrintReport(c)
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void CliforDetail.Refresh()
{
  boolean docIsModified = false
  boolean rollbackChangesAndRefresh = false
   
  this.CliforMainModuleFormHelper.checkForPendingChanges(docIsModified, rollbackChangesAndRefresh, ...)
   
  if (!(docIsModified) or rollbackChangesAndRefresh)
  {
    this.CliforMainModuleFormHelper.performRefresh()
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void CliforDetail.Save()
{
  this.CliforMainModuleFormHelper.handleSave()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void CliforDetail.Delete()
{
  this.Clifor.deleted = true
   
  try 
  {
    this.Clifor.saveToDB(...)
  }
  catch 
  {
    Qualibus.messageBox(errorMessage())
  }
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event PersonaleList.Load()
{
  Search.SearchString = ""
  Personale.collapsable = false
  Personale.collapsed = false
  if (Qualibus.GridSettingsTemp != "")
  {
    Personale.setPanelConfiguration(Qualibus.GridSettingsTemp)
  }
   
  Personale.listQBE = Row
  Personale.caption = ""
   
  boolean userCanSeeOpzioniPersonale = QappCore.Loggeduser.hasSpecificPrivilege(TabellePersonale, Execute)
  OptionsPersonale.setCommandVisible(Opzioni.getIndex(), userCanSeeOpzioniPersonale)
   
  Quickviewpersonale.visible = false
  Quickviewpersonale.collapsable = false
}


// ──────────────────────────────────

// ************************************************************************
// Event raised when a form sends a message using the SendMessage procedure
// ************************************************************************
event PersonaleList.OnSendMessage(
  string Message // Indicates the name of the message
  IDForm Sender  // Identifies the form that sent the message. IDForm type object.
  IDDocument Doc // Optional. Document associated with the message.
  string Par1    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par2    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par3    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par4    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
)
{
   
  if (Message == "BringToFront")
  {
    this.bringToFront()
  }
   
}


// ──────────────────────────────────

// ***************************************************************************
// Event raised by the panel when the user rearranges the columns in the list.
// ***************************************************************************
event PersonaleList.Personale.OnReorderColumn(
  int SourceField // An integer representing the panel field that has been dragged & dropped. It should be compared with the Me property of the panel field.
  int TargetField // An integer representing the target field of the drag & drop operation. It should be compared with the Me property of the panel field. The dragged field is inserted just before the target field taking the drop.
)
{
  Qualibus.GridSettingsTemp = Personale.getPanelConfiguration()
}


// ──────────────────────────────────

// *****************************************************
// Raised by the panel when the user double clicks on it
// *****************************************************
event PersonaleList.Personale.OnMouseDoubleClick(
  int:mouseButtons Button // Specifies which mouse button has been pressed. Refer also to the MouseButtons value list
  int X                // X position in pixels relative to the panel in which the mouse was clicked
  int Y                // Y position in pixels relative to the panel in which the mouse was clicked
  int XB               // X position in pixels relative to the browser in which the mouse was clicked
  int YB               // Y position in pixels relative to the browser in which the mouse was clicked
  int Column           // Index of the field that was clicked (-1 if the click occurred outside the fields)
  int Row              // Row clicked, from 0 to VisibleRows -1. This is -1 if the click occurred outside the fields or on the caption of the column or field
  inout boolean Cancel // Can be set to True to prevent the default action associated with the click from being run, such as execution of the field activation object.
)
{
  if (Row > 0 and Column != -1)
  {
    this.edit()
  }
}


// ──────────────────────────────────

// **********************************************
// Raised by the panel when the user clicks on it
// **********************************************
event PersonaleList.Personale.OnMouseClick(
  int:mouseButtons Button // Specifies which mouse button has been pressed. Refer also to the MouseButtons value list
  int X                // X position in pixels relative to the panel in which the mouse was clicked
  int Y                // Y position in pixels relative to the panel in which the mouse was clicked
  int XB               // X position in pixels relative to the browser in which the mouse was clicked
  int YB               // Y position in pixels relative to the browser in which the mouse was clicked
  int Column           // Index of the field that was clicked (-1 if the click occurred outside the fields)
  int Row              // Row clicked, from 0 to VisibleRows -1. This is -1 if the click occurred outside the fields or on the caption of the column or field
  inout boolean Cancel // Can be set to True to prevent the default action associated with the click from being run, such as execution of the field activation object.
)
{
  if (Button == Left or Button == Right)
  {
    if (Row > -1)
    {
      this.openQuickview()
    }
  }
}


// ──────────────────────────────────

// **********************************************************************
// Allows the visual properties of individual panel cells to be adjusted.
// **********************************************************************
event PersonaleList.Personale.OnDynamicProperties()
{
  string statoCss = Personale.STATO.CSSClass
   
  statoCss = replace(statoCss, "stato-potenziale", "")
  statoCss = replace(statoCss, "stato-attivo", "")
  statoCss = replace(statoCss, "stato-chiuso", "")
   
  if (Personale.STATO == Licenziato/Chiuso)
  {
    Personale.STATO.CSSClass = statoCss + " stato-chiuso"
  }
  if (Personale.STATO == Potenziale)
  {
    Personale.STATO.CSSClass = statoCss + " stato-potenziale"
  }
  if (Personale.STATO == Attivo)
  {
    Personale.STATO.CSSClass = statoCss + " stato-attivo"
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void PersonaleList.formShow()
{
  this.show(...)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void PersonaleList.New()
{
   
  Qualibus.messageBox("This functionality is still not supported.")
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void PersonaleList.edit()
{
  if (Personale.IDDIPENDENTE > 0)
  {
    // to see the errors in PersonaleDetail form
    Personale selectedPersonale = Personale.getFromDB(Personale.IDDIPENDENTE, ...)
     
    if (selectedPersonale)
    {
      // Create an instance of Detail form
      PersonaleDetail pd = new()
      pd.formShow(selectedPersonale, this)
    }
  }
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void PersonaleList.closequickview()
{
  Quickviewpersonale.visible = false
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void PersonaleDetail.formShow(
  Personale personale // 
  IDForm caller       // 
)
{
  this.Personale = personale
  this.PersonaleMainModuleFormHelper = MainModuleFormHelper.create(personale, CommonMainModuleTabbedView.IDForm(), this)
  this.setObjectTag("caller", caller)
  this.show(...)
  this.PersonaleMainModuleFormHelper.updateCaptionInMainForm("")
  this.PersonaleMainModuleFormHelper.initializeAllTabbedViewSubForms()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void PersonaleDetail.Back()
{
  DevTools.ToBeReviewed("to be made common!")
   
  Personale personale = this.Personale
  boolean docIsModified = personale.isModified(...)
  boolean formShouldBeClosed = true
  boolean rollbackChanges = false
   
  if (docIsModified)
  {
    int i = Qualibus.messageConfirmEx("Ci sono modifiche non ancora salvate, vuoi davvero uscire?", "Sì;No")
    if (i == null)
      return 
     
    if (i == 1)
    {
      formShouldBeClosed = true
      rollbackChanges = true
    }
    else 
    {
      formShouldBeClosed = false
    }
     
  }
   
  if (rollbackChanges)
  {
    personale.restoreOriginal()
  }
   
  if (formShouldBeClosed)
  {
    this.close(true)
    IDForm caller = this.getObjectTag("caller")
    caller.bringToFront()
    SearchFilterIMDBInteractions.initializePanelSearchQueriesRuntimeFilters(..., Personale)
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void PersonaleDetail.Refresh()
{
  boolean docIsModified = false
  boolean rollbackChangesAndRefresh = false
   
  this.PersonaleMainModuleFormHelper.checkForPendingChanges(docIsModified, rollbackChangesAndRefresh, ...)
  if (!(docIsModified) or rollbackChangesAndRefresh)
  {
    this.PersonaleMainModuleFormHelper.performRefresh()
  }
   
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void PersonaleDetail.Save()
{
  this.PersonaleMainModuleFormHelper.handleSave()
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event PersonaleDetail.Load()
{
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event EventiList.Load()
{
  Search.SearchString = ""
  Eventi.collapsable = false
  Eventi.collapsed = false
  if (Qualibus.GridSettingsTemp != "")
  {
    Eventi.setPanelConfiguration(Qualibus.GridSettingsTemp)
  }
   
//  Eventi.listQBE = Row
  Eventi.caption = ""
   
  EventiQuickviewPanel.collapsable = false
  EventiQuickviewPanel.collapsed = false
  EventiQuickviewPanel.visible = false
   
  boolean userHasExecutePrivilegeOnModelliEventi = QappCore.Loggeduser.hasSpecificPrivilege(ModelliEventi, Execute)
  ModelliEventiCommandset.setCommandVisible(OpenModelliEventi.getIndex(), userHasExecutePrivilegeOnModelliEventi)
}


// ──────────────────────────────────

// ************************************************************************
// Event raised when a form sends a message using the SendMessage procedure
// ************************************************************************
event EventiList.OnSendMessage(
  string Message // Indicates the name of the message
  IDForm Sender  // Identifies the form that sent the message. IDForm type object.
  IDDocument Doc // Optional. Document associated with the message.
  string Par1    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par2    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par3    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par4    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
)
{
  switch (Message)
  {
    case "BringToFront":
      this.bringToFront()
    break
    case "SHOW_FOR_SUB_ID":
      string ScmId = Par1
      this.formShow(ScmId)
    break
    case "ENABLE_NEW_EVENTO_BUTTON":
      NewEvento.enabled = true
    break
  }
}


// ──────────────────────────────────

// ***************************************************************************
// Event raised by the panel when the user rearranges the columns in the list.
// ***************************************************************************
event EventiList.Eventi.OnReorderColumn(
  int SourceField // An integer representing the panel field that has been dragged & dropped. It should be compared with the Me property of the panel field.
  int TargetField // An integer representing the target field of the drag & drop operation. It should be compared with the Me property of the panel field. The dragged field is inserted just before the target field taking the drop.
)
{
  Qualibus.GridSettingsTemp = Eventi.getPanelConfiguration()
}


// ──────────────────────────────────

// *****************************************************
// Raised by the panel when the user double clicks on it
// *****************************************************
event EventiList.Eventi.OnMouseDoubleClick(
  int:mouseButtons Button // Specifies which mouse button has been pressed. Refer also to the MouseButtons value list
  int X                // X position in pixels relative to the panel in which the mouse was clicked
  int Y                // Y position in pixels relative to the panel in which the mouse was clicked
  int XB               // X position in pixels relative to the browser in which the mouse was clicked
  int YB               // Y position in pixels relative to the browser in which the mouse was clicked
  int Column           // Index of the field that was clicked (-1 if the click occurred outside the fields)
  int Row              // Row clicked, from 0 to VisibleRows -1. This is -1 if the click occurred outside the fields or on the caption of the column or field
  inout boolean Cancel // Can be set to True to prevent the default action associated with the click from being run, such as execution of the field activation object.
)
{
  if (Row > 0 and Column != -1)
  {
    this.EditEvento()
  }
}


// ──────────────────────────────────

// **********************************************************************
// Allows the visual properties of individual panel cells to be adjusted.
// **********************************************************************
event EventiList.Eventi.OnDynamicProperties()
{
  string stato = Eventi.DESCRSTATOEVENTO.CSSClass
  stato = replace(stato, "stato-potenziale", "")
  stato = replace(stato, "stato-attivo", "")
  stato = replace(stato, "stato-chiuso", "")
  stato = trim(stato)
   
  if (Eventi.IDGRAVITA > 0)
  {
    Eventi.DESCRSTATOEVENTO.CSSClass = stato + " stato-chiuso"
  }
  else 
  {
    Eventi.DESCRSTATOEVENTO.CSSClass = stato + " stato-attivo"
  }
}


// ──────────────────────────────────

// **********************************************
// Raised by the panel when the user clicks on it
// **********************************************
event EventiList.Eventi.OnMouseClick(
  int:mouseButtons Button // Specifies which mouse button has been pressed. Refer also to the MouseButtons value list
  int X                // X position in pixels relative to the panel in which the mouse was clicked
  int Y                // Y position in pixels relative to the panel in which the mouse was clicked
  int XB               // X position in pixels relative to the browser in which the mouse was clicked
  int YB               // Y position in pixels relative to the browser in which the mouse was clicked
  int Column           // Index of the field that was clicked (-1 if the click occurred outside the fields)
  int Row              // Row clicked, from 0 to VisibleRows -1. This is -1 if the click occurred outside the fields or on the caption of the column or field
  inout boolean Cancel // Can be set to True to prevent the default action associated with the click from being run, such as execution of the field activation object.
)
{
  if (Button == Left)
  {
    if (Row != -1)
    {
      this.openQuickview()
    }
  }
}


// ──────────────────────────────────

// **********************************************************************
// Allows the visual properties of individual panel cells to be adjusted.
// **********************************************************************
event EventiList.EventiQuickviewPanel.OnDynamicProperties()
{
  if (EventiQuickviewPanel.IDGRAVITA <= 0)
  {
    EventiQuickviewPanel.Datichiusura.setGroupVisible(false)
  }
  else 
  {
    EventiQuickviewPanel.Datichiusura.setGroupVisible(true)
  }
   
  EventiQuickviewPanel.caption = Eventi.DESCRTITOLO
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void EventiList.formShow(
  string SCMID // Write a comment for this parameter or press backspace to delete this comment
)
{
  if (SCMID == TuttiGliEventiSpecificInfo)
  {
    this.SingleClassModeID = -1
  }
  else 
  {
    this.SingleClassModeID = toInteger(SCMID)
  }
  this.show(...)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void EventiList.EditEvento()
{
  if (Eventi.IDEVENTO > 0)
  {
    Evento selectedEvento = Evento.getFromDB(Eventi.IDEVENTO, ...)
    if (selectedEvento)
    {
      EventiDetail ed = new()
      ed.formShow(selectedEvento, this, this.SingleClassModeID > -1)
    }
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void EventiList.OpenModelliEventi()
{
  int eventiSubId = 0
  if (this.SingleClassModeID > 0)
  {
    eventiSubId = this.SingleClassModeID
  }
  SearchFilterIMDBInteractions.initializePanelSearchQueriesRuntimeFilters(..., ModelliEventi, eventiSubId)
  ModelliEventoList mel = new()
  if (this.SingleClassModeID > 0)
  {
    ClasseEvento ce = ClasseEvento.get(this.SingleClassModeID)
     
    mel.caption = formatMessage("Modelli Evento (|1)", ce.DESCRCLASSE, ...)
  }
  mel.showForm()
}


// ──────────────────────────────────



// ──────────────────────────────────

// ***********************
// Reload the list from DB
// ***********************
private void EventiList.ReloadEventiList()
{
  Qualibus.messageBox("TODO")
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void EventiList.openopzioni()
{
  MainPageFormInstanceFactory.AssegnaRuoli(TabelleEventi)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void EventiList.Close()
{
  EventiQuickviewPanel.visible = false
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void EventiList.openQuickview()
{
  int idSelectedEvento = Eventi.IDEVENTO
  if (idSelectedEvento > 0)
  {
    Evento e = Evento.getFromDB(idSelectedEvento, quickLoad)
    EventiQuickviewPanel.setDocument(e, true)
    EventiQuickviewPanel.visible = true
  }
  else 
  {
    EventiQuickviewPanel.visible = false
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void EventiDetail.Back()
{
   
  DevTools.ToBeReviewed("to be made common!")
   
  Evento evento = this.Evento
  boolean docIsModified = evento.isModified(...)
  boolean formShouldBeClosed = true
  boolean rollbackChanges = false
   
  if (docIsModified)
  {
    int i = Qualibus.messageConfirmEx("Ci sono modifiche non ancora salvate, vuoi davvero uscire?", "Sì;No")
    if (i == null)
      return 
     
    if (i == 1)
    {
      formShouldBeClosed = true
      rollbackChanges = true
    }
    else 
    {
      formShouldBeClosed = false
    }
     
  }
   
  if (rollbackChanges)
  {
    evento.restoreOriginal()
  }
   
  if (formShouldBeClosed)
  {
    this.close(true)
    IDForm caller = this.getObjectTag("caller")
    caller.bringToFront()
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void EventiDetail.Save()
{
  this.EventiMainModuleFormHelper.handleSave()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void EventiDetail.Refresh()
{
  boolean docIsModified = false
  boolean rollbackChangesAndRefresh = false
   
  this.EventiMainModuleFormHelper.checkForPendingChanges(docIsModified, rollbackChangesAndRefresh, ...)
  if (!(docIsModified) or rollbackChangesAndRefresh)
  {
    this.EventiMainModuleFormHelper.performRefresh()
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void EventiDetail.formShow(
  Evento evento                   // Write a comment for this parameter or press backspace to delete this comment
  IDForm caller                   // 
  boolean singleClassModeIsActive // 
)
{
  this.Evento = evento
  this.EventiMainModuleFormHelper = MainModuleFormHelper.create(evento, CommonMainModuleTabbedView.IDForm(), this)
  this.setObjectTag("caller", caller)
  this.show(...)
   
  string additionalCaption = ""
  if (singleClassModeIsActive)
  {
    additionalCaption = caller.caption
  }
  this.EventiMainModuleFormHelper.updateCaptionInMainForm(additionalCaption)
  this.EventiMainModuleFormHelper.initializeAllTabbedViewSubForms()
   
  if (evento.isLocked())
  {
    Save.visible = false
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void EventiDetail.OpenModelliEventi()
{
  if (this.Evento and this.Evento.IDEVENTO > 0)
  {
    ModelloEvento me = ModelloEvento.getFromDB(this.Evento.IDTEMPLATEEVENTO, quickLoad)
    ModelloEventoDetail med = ModelloEventoDetail.newInstance(MDI, ...)
    med.formShow(me, this)
  }
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event EventiDetail.Load()
{
}


// ──────────────────────────────────

// ************************************************************************
// Event raised when a form sends a message using the SendMessage procedure
// ************************************************************************
event EventiDetail.OnSendMessage(
  string Message // Indicates the name of the message
  IDForm Sender  // Identifies the form that sent the message. IDForm type object.
  IDDocument Doc // Optional. Document associated with the message.
  string Par1    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par2    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par3    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par4    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
)
{
  if (Message == "SAVE")
  {
    this.EventiMainModuleFormHelper.handleSave()
  }
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event NuovoEventoModalForm.Load()
{
  Modelloeventoselectionpanel.listQBE = Row
  DevTools.ToBeReviewed("this form has a main panel DB based with 2 fields computed in the master query: those 2 must be done in a DO class, when we'll remove IMDB forms we'll fix also this!")
}


// ──────────────────────────────────

// ********************************************
// Event raised by the form before it is closed
// ********************************************
event NuovoEventoModalForm.Unload(
  inout int Cancel // If set to True, closure of the form is canceled.
  boolean Confirm  // Represents the user's selection for closing modal forms. True if the user confirms their choice, otherwise False.
)
{
  this.sendMessageToEventiListFormToReEnableNewEventoButton()
}


// ──────────────────────────────────

// *****************************************************
// Raised by the panel when the user double clicks on it
// *****************************************************
event NuovoEventoModalForm.Modelloeventoselectionpanel.OnMouseDoubleClick(
  int:mouseButtons Button // Specifies which mouse button has been pressed. Refer also to the MouseButtons value list
  int X                // X position in pixels relative to the panel in which the mouse was clicked
  int Y                // Y position in pixels relative to the panel in which the mouse was clicked
  int XB               // X position in pixels relative to the browser in which the mouse was clicked
  int YB               // Y position in pixels relative to the browser in which the mouse was clicked
  int Column           // Index of the field that was clicked (-1 if the click occurred outside the fields)
  int Row              // Row clicked, from 0 to VisibleRows -1. This is -1 if the click occurred outside the fields or on the caption of the column or field
  inout boolean Cancel // Can be set to True to prevent the default action associated with the click from being run, such as execution of the field activation object.
)
{
  this.ButtonOk()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void NuovoEventoModalForm.showForm(
  IDForm callerForm // 
  int idClasse      // 
)
{
  this.CallerForm = callerForm
  DataSelectionpanel.DataeventoSelectionpanel = today()
  Modelloeventoselectionpanel.CLASSE.setVisible(idClasse <= 0)
   
  if (idClasse > 0)
  {
    ClasseEvento ce = ClasseEvento.get(idClasse)
    if (ce)
    {
      this.caption = this.caption + " (Classe: " + ce.DESCRCLASSE + ")"
    }
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void NuovoEventoModalForm.ButtonOk()
{
  int idSelectedModelloEvento = Modelloeventoselectionpanel.IDTEMPLATEEVENTOModelloEvento
   
  if (idSelectedModelloEvento <= 0)
  {
    Qualibus.messageBox("E' necessario selezionare il modello evento.")
    return 
  }
   
  ModelloEvento me = ModelloEvento.getFromDB(idSelectedModelloEvento, quickLoad)
   
  if (me == null or me.IDTEMPLATEEVENTO <= 0)
  {
    Qualibus.messageBox("E' necessario selezionare il modello evento.")
    return 
  }
   
  if (DataSelectionpanel.DataeventoSelectionpanel == null or DataSelectionpanel.DataeventoSelectionpanel < toDate(1900, 12, 31))
  {
    Qualibus.messageBox("Data non valida.")
    DataSelectionpanel.Dataevento.setErrorText("Data non valida.")
    return 
  }
   
  // create the event
  Evento e = Evento.create(QappCore.Loggeduser.IDUTENTE, QappCore.Loggeduser.IDUTENTE, QappCore.Loggeduser.IDUTENTE, me.IDTEMPLATEEVENTO, DataSelectionpanel.DataeventoSelectionpanel, me.IDAMBITO, me.IDTIPOLOGIA)
   
  if (e)
  {
    EventiDetail ed = EventiDetail.newInstance(...)
    ed.formShow(e, this.CallerForm, false)
     
    this.close(...)
  }
  else 
  {
    Qualibus.messageBox("Errore nella creazione del nuovo evento.")
    return 
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void NuovoEventoModalForm.ButtonAnnulla()
{
  this.close(...)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void NuovoEventoModalForm.sendMessageToEventiListFormToReEnableNewEventoButton()
{
  // when we click on new evento we disable the button, after closing the modello evento selection form we need to re enable it, we do it with send message on the caller form
  this.CallerForm.sendMessage("ENABLE_NEW_EVENTO_BUTTON", ...)
}


// ──────────────────────────────────

// *******************************************************************
// Event raised by the tree when a node is expanded for the first time
// *******************************************************************
event Documenti.FolderTree.OnExpandDoc(
  IDDocument Doc       // The document that was expanded for the first time. The value of the parameter is derived from the IDDocument library.
  inout boolean Cancel // A boolean output parameter. If set to True, it prevents the expansion of the node.
)
{
  Cartella cartella = (Cartella)Doc
  if (cartella)
  {
    cartella.CaricaCartelleFiglie()
  }
}


// ──────────────────────────────────

// ***********************************************
// Event raised by a tree when a node is activated
// ***********************************************
event Documenti.FolderTree.OnActivateDoc(
  IDDocument Doc       // The document that was activated. The value of the parameter is derived from the IDDocument library.
  inout boolean Cancel // A boolean output parameter. If set to True, it prevents activation of the node.
)
{
  if (Doc and Cartella.isMyInstance(Doc))
  {
    this.FocusedCartella = (Cartella)Doc
    IDCollection loadedDocumenti of Documento = DocDocumenti.collection
    loadedDocumenti.moveFirst()
     
    boolean documentiShouldBeLoaded = false
     
    if (loadedDocumenti.count() <= 0)
    {
      documentiShouldBeLoaded = true
       
    }
    else 
    {
      Documento d = (Documento)loadedDocumenti.getAt()
      if (d.IDCARTELLA != this.FocusedCartella.IDCARTELLA)
      {
         documentiShouldBeLoaded = true
      }
    }
     
    if (documentiShouldBeLoaded)
    {
      this.populateDocumentiPanel()
      this.MoveToDocumenti()
    }
     
     
  }
  boolean aFolderIsFocusd = Doc != null
  if (aFolderIsFocusd)
  {
    this.showDropPanel()
    New.visible = true
  }
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event Documenti.Load()
{
  FolderTree.collapsable = false
  FolderTree.activateOnExpand = false
  ExportDocuments.visible = false
  AssegnaRuoli.visible = false
  Revision.collapsable = false
  Revision.visible = true
   
  New.visible = false
  Back.visible = false
   
  // drop panel specific
  this.initializeDropPanel()
}


// ──────────────────────────────────

// ************************************************************************
// Event raised when a form sends a message using the SendMessage procedure
// ************************************************************************
event Documenti.OnSendMessage(
  string Message // Indicates the name of the message
  IDForm Sender  // Identifies the form that sent the message. IDForm type object.
  IDDocument Doc // Optional. Document associated with the message.
  string Par1    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par2    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par3    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par4    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
)
{
  if (Message == "DocumentAdded")
  {
    Cartella cartella = (Cartella)Doc
    if (cartella)
    {
      this.FocusedCartella = cartella
      this.populateDocumentiPanel()
    }
  }
  if (Message == "FILE_UPLOAD_COMPLETED")
  {
    IDArray uploadedFiles = UIBusinessLogic.UIBusinessLogicCommunication.GetUploadedFilesArray()
    IDCollection documentsTobeInserted of DocumentoInserter = DocumentoInserter.prepareDocumentoInserterCollection(this.FocusedCartella, uploadedFiles)
    MultipleDocumentInserter.showForm(this.IDForm(), documentsTobeInserted, Modal)
  }
  if (Message == "DocumentSelected")
  {
    Documento selectedDocument = (Documento)Doc
    if (selectedDocument)
    {
      this.handleNewFromExistingDocument(selectedDocument)
    }
  }
}


// ──────────────────────────────────

// **********************************************************************
// Allows the visual properties of individual panel cells to be adjusted.
// **********************************************************************
event Documenti.DocDocumenti.OnDynamicProperties()
{
  // tooltips for onlyicon buttons
  DocDocumenti.OPEN.tooltip("Apri in Modifica")
  DocDocumenti.DOWNLOAD.tooltip("Download")
  DocDocumenti.REVISION.tooltip("Revisioni")
   
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Documenti.showForm()
{
  this.loadTree()
  IDCollection coll of Documento = new()
  DocDocumenti.setCollection(coll, ...)
  this.show(MDI)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Documenti.loadTree()
{
  IDCollection firstLevelFolders of Cartella = Cartella.getCollectionOfVisibileCartelle(QappCore.Loggeduser, ...)
  FolderTree.collection = firstLevelFolders
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Documenti.buttonLinks()
{
  Documento doc = DocDocumenti.document
  if (doc)
  {
    int numberOfLinks = toInteger(doc.getTag("linksCount"))
    if (numberOfLinks == 0)
    {
      Qualibus.messageBox("<i>Non ci sono collegamenti da mostrare</i>")
    }
    else 
    {
      Collegamenti.showForm(doc)
    }
  }
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Documenti.Refresh()
{
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Documenti.buttonOpen()
{
  if (DocDocumenti.document)
  {
    Documento d = DocDocumenti.document
    OnlyOfficeDocumentOpener.open(d, this, view)
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Documenti.Distributed()
{
  DistributedDocuments.showForm()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Documenti.download()
{
  Documento d = DocDocumenti.document
  if (d)
  {
    boolean isDownloadable = d.isDownloadable()
    if (isDownloadable)
    {
      Qualibus.handleDocumentDownload(d)
    }
    else 
    {
      Qualibus.messageBox("Nessuna revisione approvata, impossibile scaricare il documento")
    }
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Documenti.Opzioni()
{
  MainPageFormInstanceFactory.AssegnaRuoli(TabelleDocumenti)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Documenti.ExportDocuments()
{
  ExportCartellaForm.showForm(this.FocusedCartella)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Documenti.LoadPermessi()
{
  AssegnaRuoli.showForm(this.FocusedCartella)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Documenti.MoveToDocumenti()
{
  MainTabbedView.moveTo(1)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Documenti.moveToRevisioni()
{
  if (!(this.FocusedCartella.hasOnlyReadPrivilege(QappCore.Loggeduser)))
  {
    Documento d = DocDocumenti.document
    d.loadDocumentRevisions(...)
    Revision.setCollection(d.Revisions, true)
    MainTabbedView.moveTo(2)
    this.handleBackButtonVisibility()
  }
  else 
  {
    Qualibus.messageBox("Non si possiede il ruolo per visualizzare queste informazioni")
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Documenti.moveToDistribuzioni()
{
  if (this.FocusedCartella.HasDistributePrivilege(QappCore.Loggeduser))
  {
    MainTabbedView.moveTo(3)
    this.handleBackButtonVisibility()
  }
  else 
  {
    Qualibus.messageBox("Non si possiede il ruolo per visualizzare queste informazioni")
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Documenti.Back()
{
  if (Revision.hasFocus())
  {
    MainTabbedView.moveTo(1)
  }
  else if (Distribution.hasFocus())
  {
    MainTabbedView.moveTo(2)
  }
  this.handleBackButtonVisibility()
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Documenti.showDropPanel()
{
  Droppanel.visible = true
  UIBusinessLogic.UIBusinessLogicCommunication.SetFileUploadMode(multpleFiles)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Documenti.NewDocumentWithoutFile()
{
  DocumentoInserter di = DocumentoInserter.create(this.FocusedCartella, WithoutFile, ...)
  DocumentInserter.showForm(this.IDForm(), di, Modal)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Documenti.newFromFile()
{
  UIBusinessLogic.UIBusinessLogicCommunication.SetFileUploadMode(singleFile)
  DocumentoInserter di = DocumentoInserter.create(this.FocusedCartella, FromFile, ...)
  DocumentInserter.showForm(this.IDForm(), di, Modal)
}


// ──────────────────────────────────



// ──────────────────────────────────

// ******************************************************************
// back command is visibile only in revisioni and distribuzioni pages
// ******************************************************************
private void Documenti.handleBackButtonVisibility()
{
  if (MainTabbedView.selectedPage() != DocDocumenti.me())
  {
    Back.visible = true
  }
  else 
  {
    Back.visible = false
  }
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event Collegamenti.Load()
{
  VDOCCOLLEGATISource.listQBE = No
  VDOCCOLLEGATIDestination.listQBE = No
  VMODULEDOCUMENTCOLLEGATI.listQBE = No
}


// ──────────────────────────────────

// **********************************************************************
// Allows the visual properties of individual panel cells to be adjusted.
// **********************************************************************
event Collegamenti.VDOCCOLLEGATISource.OnDynamicProperties()
{
  // trick copied from Main Form to avoid broken-image
  if (VDOCCOLLEGATISource.CODDOCUMENTO == "" and VDOCCOLLEGATISource.DESCRDOCUMENTO == "")
  {
    VDOCCOLLEGATISource.DisplayIcon.image("")
  }
}


// ──────────────────────────────────

// **********************************************************************
// Allows the visual properties of individual panel cells to be adjusted.
// **********************************************************************
event Collegamenti.VDOCCOLLEGATIDestination.OnDynamicProperties()
{
  // trick copied from Main Form to avoid broken-image
  if (VDOCCOLLEGATIDestination.CODDOCUMENTO == "" and VDOCCOLLEGATIDestination.DESCRDOCUMENTO == "")
  {
    VDOCCOLLEGATIDestination.DisplayIcon.image("")
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Collegamenti.showForm(
  Documento document // Write a comment for this parameter or press backspace to delete this comment
)
{
  // Computation of caption
  string documentCompleteDescription = if(document.CODDOCUMENTO == "", document.DESCRDOCUMENTO, document.CODDOCUMENTO + " - " + document.DESCRDOCUMENTO)
  string computedFormCaption = formatMessage("Collegamenti di "|1"", documentCompleteDescription, ...)
  this.caption = computedFormCaption
   
   
  // first Tab
  IDCollection linkedDocumentsSource of VDOCCOLLEGATI = document.GetDocCollegatiCollection(Source)
  if (linkedDocumentsSource.count() > 0)
  {
    VDOCCOLLEGATISource.setCollection(linkedDocumentsSource, true)
  }
  else 
  {
    VDOCCOLLEGATISource.visible = false
  }
   
  // second Tab
  IDCollection linkedDocumentsDestination of VDOCCOLLEGATI = document.GetDocCollegatiCollection(Destination)
   
  if (linkedDocumentsDestination.count() > 0)
  {
    VDOCCOLLEGATIDestination.setCollection(linkedDocumentsDestination, true)
  }
  else 
  {
    VDOCCOLLEGATIDestination.visible = false
  }
   
  // third Tab
  IDCollection linkedModuleDocumentsCollection of VMODULEDOCUMENTCOLLEGATI = document.GetModuleDocumentLinksCollection()
   
  if (linkedModuleDocumentsCollection.count() > 0)
  {
    VMODULEDOCUMENTCOLLEGATI.setCollection(linkedModuleDocumentsCollection, true)
  }
  else 
  {
    VMODULEDOCUMENTCOLLEGATI.visible = false
  }
   
}


// ──────────────────────────────────

// *********************************************************************************************************************
// method used to download file from all the COD Documento and DESCR documento fields in the panels of Collegamenti form
// *********************************************************************************************************************
public void Collegamenti.download()
{
   
  DevTools.ToBeReviewed("this code was done for Qdocs old versions, still be to be reviewed seriously for Qualibus web")
  Documento d = null
   
  VDOCCOLLEGATI doccollegati = null
   
  switch (LinkedDocsTabbedView.selectedPage())
  {
    case VDOCCOLLEGATISource.me():
      doccollegati = VDOCCOLLEGATISource.document
    break
    case VDOCCOLLEGATIDestination.me():
      doccollegati = VDOCCOLLEGATIDestination.document
    break
  }
   
  int idDocuemntToBeReturned = doccollegati.IDLINKEDDOCUMENT
  d = Documento.getFromDB(idDocuemntToBeReturned, ...)
   
  Qualibus.handleDocumentDownload(d)
}


// ──────────────────────────────────

// ***************************************************************
// Event raised by the panel at the start of the data saving step.
// ***************************************************************
event SearchDocument.SearchIMDB.BeforeCommit(
  inout boolean Cancel // If set to True, cancels the saving of data.
)
{
  this.loadPanelData()
}


// ──────────────────────────────────

// **************************************************************************************
// Event raised to the form when it is activated, meaning when it is brought to the front
// **************************************************************************************
event SearchDocument.Activate()
{
//  SearchIMDB.USERFILTERSearchCondition = ""
//  SearchIMDB.USERFILTER.setFocus(...)
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event SearchDocument.Load()
{
  documents.listQBE = false
  documents.collapsable = false
  documents.caption = ""
  this.Enablesearch = false
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void SearchDocument.showForm()
{
  this.show(MDI)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void SearchDocument.ButtonCerca()
{
  this.loadPanelData()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void SearchDocument.loadPanelData()
{
  this.updateControls()
   
  IDCollection searchResults of Documento = new()
  select into collection (searchResults)
  from 
    Documento // master table
  where
    (CODDOCUMENTO like ("%" + SearchIMDB.USERFILTERSearchCondition + "%")) or (DESCRDOCUMENTO like ("%" + SearchIMDB.USERFILTERSearchCondition + "%")) or (SearchIMDB.USERFILTERSearchCondition == "%")
   
   
  IDCollection filteredSearchResults of Documento = new()
  for each Documento dd in searchResults
  {
    if (dd.isValid())
    {
      if (dd.isVisibleTo(QappCore.Loggeduser))
      {
         filteredSearchResults.add(dd)
      }
    }
  }
   
  documents.setCollection(filteredSearchResults, true)
}


// ──────────────────────────────────

// ************************************************************
// Spiega quale elaborazione viene eseguita da questa procedura
// ************************************************************
private void SearchDocument.buttonScaricaFile()
{
  Documento d = documents.document
   
  if (d)
  {
    Qualibus.handleDocumentDownload(d)
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void SearchDocument.buttonOpen()
{
  if (documents.document)
  {
//    ARTDOCUMENTI ds = documents.document
     
     
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void DistributedDocuments.showForm()
{
  this.Enablesearch = false
  this.loadPanelData(...)
  this.show(MDI)
}


// ──────────────────────────────────

// **********************************************************************
// set the panel collection after retrieving it with the dedicated method
// **********************************************************************
private void DistributedDocuments.loadPanelData(
  optional string filterCondition = "" // 
)
{
  IDCollection coll of Documento = Documento.getDocumentsToBeReadByUser(QappCore.Loggeduser)
   
  if (filterCondition != "")
  {
    IDCollection filteredColl of Documento = new()
     
    filterCondition = lower(filterCondition)
     
    for each Documento dd in coll
    {
      boolean codeMatchesFilter = find(lower(dd.CODDOCUMENTO), filterCondition, ...) != 0
      boolean descriptionMatchesFilter = find(lower(dd.DESCRDOCUMENTO), filterCondition, ...) != 0
      if (codeMatchesFilter or descriptionMatchesFilter)
      {
         filteredColl.add(dd)
      }
    }
     
    LISTADOCUMENTI.setCollection(filteredColl, true)
  }
  else 
  {
    LISTADOCUMENTI.setCollection(coll, true)
  }
   
}


// ──────────────────────────────────

// ************************************************************
// Spiega quale elaborazione viene eseguita da questa procedura
// ************************************************************
private void DistributedDocuments.buttonDownload()
{
  Documento d = LISTADOCUMENTI.document
  if (d)
  {
    Qualibus.handleDocumentDownload(d)
    this.loadPanelData(...)
  }
}


// ──────────────────────────────────

// **************************************************************************************
// Event raised to the form when it is activated, meaning when it is brought to the front
// **************************************************************************************
event DistributedDocuments.Activate()
{
//  SearchIMDB.USERFILTERSearchCondition = ""
//  SearchIMDB.USERFILTER.setFocus(...)
}


// ──────────────────────────────────

// **********************************************************
// Event raised to the form when it is sent to the background
// **********************************************************
event DistributedDocuments.Deactivate(
  inout boolean Cancel // If set to True, the form is left on top. The other form that should have come to the front is therefore left in the background.
)
{
  this.Enablesearch = false
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event DistributedDocuments.Load()
{
  LISTADOCUMENTI.listQBE = No
  LISTADOCUMENTI.collapsable = false
}


// ──────────────────────────────────

// ***************************************************************
// Event raised by the panel at the start of the data saving step.
// ***************************************************************
event DistributedDocuments.SearchIMDB.BeforeCommit(
  inout boolean Cancel // If set to True, cancels the saving of data.
)
{
  string userFilter = SearchIMDB.USERFILTERSearchCondition
  this.loadPanelData(userFilter)
}


// ──────────────────────────────────

// *********************************************************************
// Event raised after saving the data for an edited row to the database.
// *********************************************************************
event ModelliEventoList.SearchPanelCURRENTLYNOTATTACHED.AfterUpdate()
{
}


// ──────────────────────────────────

// **************************************************************
// Event raised by the panel at the end of the data saving cycle.
// **************************************************************
event ModelliEventoList.SearchPanelCURRENTLYNOTATTACHED.AfterCommit(
  int RowsUpdated  // Number of rows that have been updated or inserted successfully.
  int RowsInErrors // Number of rows that were not updated or inserted due to database errors.
)
{
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event ModelliEventoList.Load()
{
  Search.Searchstring = ""
  ModelliEvento.collapsable = false
  ModelliEvento.collapsed = false
  ModelliEvento.listQBE = Row
   
  ModelliEvento.caption = ""
   
  ModelloeventoQuickview.visible = false
  ModelloeventoQuickview.collapsed = false
  ModelloeventoQuickview.collapsable = false
}


// ──────────────────────────────────

// ************************************************************************
// Event raised when a form sends a message using the SendMessage procedure
// ************************************************************************
event ModelliEventoList.OnSendMessage(
  string Message // Indicates the name of the message
  IDForm Sender  // Identifies the form that sent the message. IDForm type object.
  IDDocument Doc // Optional. Document associated with the message.
  string Par1    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par2    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par3    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par4    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
)
{
  switch (Message)
  {
    case "CLASSE_EVENTO_SELECTED":
      ClasseEvento classeEvento = (ClasseEvento)Doc
      this.SelectedClasseEvento = classeEvento
      this.proceedOpeningComportamentoSelectionForm(classeEvento)
    break
    case "COMPORTAMENTO_SELECTED":
      ModelloEventoComportamentoSelection comportamento = (ModelloEventoComportamentoSelection)Doc
      this.proceedeOpeningModelloEventoDetailForm(comportamento.Comportamento)
    break
    case "REOPEN":
      ModelloEvento me = (ModelloEvento)Doc
      if (me)
         this.openModelloEventoDetailForm(me)
    break
  }
}


// ──────────────────────────────────

// **********************************************
// Raised by the panel when the user clicks on it
// **********************************************
event ModelliEventoList.ModelliEvento.OnMouseClick(
  int:mouseButtons Button // Specifies which mouse button has been pressed. Refer also to the MouseButtons value list
  int X                // X position in pixels relative to the panel in which the mouse was clicked
  int Y                // Y position in pixels relative to the panel in which the mouse was clicked
  int XB               // X position in pixels relative to the browser in which the mouse was clicked
  int YB               // Y position in pixels relative to the browser in which the mouse was clicked
  int Column           // Index of the field that was clicked (-1 if the click occurred outside the fields)
  int Row              // Row clicked, from 0 to VisibleRows -1. This is -1 if the click occurred outside the fields or on the caption of the column or field
  inout boolean Cancel // Can be set to True to prevent the default action associated with the click from being run, such as execution of the field activation object.
)
{
  if (Button == Left)
  {
    if (Row != -1)
    {
      this.openModelloEventoQuickview()
    }
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void ModelliEventoList.showForm()
{
  this.show(MDI)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void ModelliEventoList.Edit()
{
  if (ModelliEvento.IDTEMPLATEEVENTO > 0)
  {
    ModelloEvento selectedModelloEvento = ModelloEvento.getFromDB(ModelliEvento.IDTEMPLATEEVENTO, ...)
    if (selectedModelloEvento)
    {
      this.openModelloEventoDetailForm(selectedModelloEvento)
    }
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void ModelliEventoList.New()
{
  ClasseSelection.showForm(this)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void ModelliEventoList.openModelloEventoDetailForm(
  ModelloEvento modello // 
)
{
  if (modello == null)
    Qualibus.DTTLogMessage("NULL modello evento", ..., DTTError)
   
  modello.loadAllCollections()
   
  ModelloEventoDetail med = ModelloEventoDetail.newInstance(MDI, ...)
  med.formShow(modello, this)
   
  DevTools.ToBeReviewed("to support devextreme diagram saving we store the subform instance so we can send it a message for saving")
  Qualibus.ModelloEventoDetailVariableForSavingDiagram = med
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void ModelliEventoList.proceedOpeningComportamentoSelectionForm(
  ClasseEvento selectedClasse // 
)
{
  if (selectedClasse and selectedClasse.IDCLASSE > 0)
  {
    ComportamentoModelloEventoSelection.showForm(this)
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void ModelliEventoList.proceedeOpeningModelloEventoDetailForm(
  string selectedComportamento // 
)
{
  ModelloEvento me = ModelloEvento.create(this.SelectedClasseEvento, selectedComportamento)
  ModelloEventoDetail med = ModelloEventoDetail.newInstance(MDI, ...)
  med.formShow(me, this)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void ModelliEventoList.openModelloEventoQuickview()
{
  int idModelloEventoSelected = ModelliEvento.IDTEMPLATEEVENTO
  if (idModelloEventoSelected > 0)
  {
    ModelloEvento me = ModelloEvento.getFromDB(idModelloEventoSelected, quickLoad)
    ModelloeventoQuickview.setDocument(me, true)
    ModelloeventoQuickview.caption = me.DESCRTEMPLATE
    ModelloeventoQuickview.visible = true
  }
  else 
  {
    ModelloeventoQuickview.visible = false
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void ModelliEventoList.close()
{
  ModelloeventoQuickview.visible = false
}


// ──────────────────────────────────

// ************************************************************************
// Event raised when a form sends a message using the SendMessage procedure
// ************************************************************************
event ModelloEventoDetail.OnSendMessage(
  string Message // Indicates the name of the message
  IDForm Sender  // Identifies the form that sent the message. IDForm type object.
  IDDocument Doc // Optional. Document associated with the message.
  string Par1    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par2    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par3    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par4    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
)
{
  if (Message == "STORE_JSON")
  {
    Qualibus.DTTLogMessage(formatMessage("Storing diagram for modello |1", this.ModelloEvento.IDTEMPLATEEVENTO, ...), 12345, ...)
    string jsonDiagram = Par1
    this.ModelloEvento.DIAGRAMJSON = jsonDiagram
    this.ModelloEvento.saveToDB(...)
  }
   
  if (Message == "DELETE_MODELLOEVENTO")
  {
//    this.ModelloEvento.deleted = true
//    this.ModelloEvento.saveToDB(...)
     
    Qualibus.messageBox("TODO")
  }
   
  if (Message == "WORKFLOW_TYPE_CHANGED")
  {
    this.handleWorflowtypeChange(Par1)
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void ModelloEventoDetail.formShow(
  ModelloEvento modelloEvento // Write a comment for this parameter or press backspace to delete this comment
  IDForm caller               // 
)
{
  this.ModelloEvento = modelloEvento
  this.ModelliEventiMainModuleFormHelper = MainModuleFormHelper.create(modelloEvento, CommonMainModuleTabbedView.IDForm(), this)
  this.setObjectTag("caller", caller)
  this.ModelloEvento.setObjectTag("caller", this)
  this.show(...)
  this.ModelliEventiMainModuleFormHelper.updateCaptionInMainForm("")
  this.ModelliEventiMainModuleFormHelper.initializeAllTabbedViewSubForms()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void ModelloEventoDetail.Back()
{
  DevTools.ToBeReviewed("to be made common!")
   
  ModelloEvento modello = this.ModelloEvento
  boolean docIsModified = modello.isModified(...)
   
  boolean formShouldBeClosed = true
  boolean rollbackChanges = false
   
  if (docIsModified)
  {
    int i = Qualibus.messageConfirmEx("Ci sono modifiche non ancora salvate, vuoi davvero uscire?", "Sì;No")
    if (i == null)
      return 
     
    if (i == 1)
    {
      formShouldBeClosed = true
      rollbackChanges = true
    }
    else 
    {
      formShouldBeClosed = false
    }
     
  }
   
  if (rollbackChanges)
  {
    modello.restoreOriginal()
  }
   
  if (formShouldBeClosed)
  {
    this.close(true)
    IDForm caller = this.getObjectTag("caller")
    caller.bringToFront()
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void ModelloEventoDetail.Refresh()
{
   
  boolean docIsModified = false
  boolean rollbackChangesAndRefresh = false
   
  this.ModelliEventiMainModuleFormHelper.checkForPendingChanges(docIsModified, rollbackChangesAndRefresh, ...)
   
  if (!(docIsModified) or rollbackChangesAndRefresh)
  {
    this.ModelliEventiMainModuleFormHelper.performRefresh()
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void ModelloEventoDetail.Save()
{
   
  // handle Save in case of modello evento saves also the workflow (through Main Module UI Logic.perform Specific Saving Operations)
  this.ModelliEventiMainModuleFormHelper.handleSave()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void ModelloEventoDetail.Duplica()
{
  boolean docIsModified = this.ModelloEvento.isModified(...)
   
  boolean proceedeToSave = false
   
  if (docIsModified)
  {
    int response = Qualibus.messageConfirmEx("Desideri salvare le modifiche effettuate?", "Sì;No;Annulla")
    if (response == null)
      return 
     
    if (response == 1)
    {
      proceedeToSave = true
    }
    else if (response == 2)
    {
      proceedeToSave = false
    }
    else 
    {
      return 
    }
     
  }
   
  if (proceedeToSave)
  {
    this.Save()
  }
   
  ModelloEvento duplicatedModelloEvento = ModelloEvento.duplicateModelloEvento(this.ModelloEvento)
   
  ModelloEventoDetail med = this.newInstance(...)
  med.formShow(duplicatedModelloEvento, this.IDForm())
   
   
   
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void ModelloEventoDetail.Delete()
{
  DeleteConfirmationFrom dcf = DeleteConfirmationFrom.newInstance(Modal, ...)
  dcf.ShowForm(this.IDForm(), "DELETE_MODELLOEVENTO", this.ModelloEvento)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void ModelloEventoDetail.handleWorflowtypeChange(
  string:eventiBehaviours behaviour // 
)
{
  ModelloEvento me = this.ModelloEvento
  string worfklowType = behaviour
   
  if (worfklowType == Workflow)
  {
    if (me.GetDiagram() == null)
    {
      me.initializeDiagramObject()
    }
     
    IDForm workflowSubform = this.ModelliEventiMainModuleFormHelper.createWorkflowDiagramSubform()
    IDDocument loadDoc = new()
    loadDoc = (IDDocument)me
    workflowSubform.sendMessage(load, me, ...)
//     
    IDDocument doc = new()
    doc.setObjectTag("subform", workflowSubform)
    CommonMainModuleTabbedView.sendMessage("WORKFLOW_TYPE_CHANGED", doc, Workflow, ...)
  }
  else if (worfklowType == Normal)
  {
    IDForm disposizioniSubform = this.ModelliEventiMainModuleFormHelper.CreateModelloDisposizioniSubform()
    IDDocument loadDoc = new()
    loadDoc = (IDDocument)me
    disposizioniSubform.sendMessage(load, me, ...)
     
    IDDocument doc = new()
    doc.setObjectTag("subform", disposizioniSubform)
    CommonMainModuleTabbedView.sendMessage("WORKFLOW_TYPE_CHANGED", doc, Normal, ...)
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void ClasseSelection.showForm(
  IDForm caller // Write a comment for this parameter or press backspace to delete this comment
)
{
  this.CallerForm = caller
   
  ClasseSelection.collapsable = false
   
  this.AvailableClassiCollection = ClasseEvento.getClassesBasedOnUserRole(QappCore.Loggeduser, Immissione)
  this.UpdateItemList(...)
   
  this.show(Modal)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void ClasseSelection.InformCallerAboutSelectedClasse()
{
  ClasseEvento classeEvento = ClasseSelection.document
  if (classeEvento and classeEvento.IDCLASSE > 0)
  {
    this.CallerForm.sendMessage("CLASSE_EVENTO_SELECTED", classeEvento, ...)
    this.close(true)
  }
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void ClasseSelection.Reset()
{
  SearchPanel.FiltroSearchPanel = ""
  this.UpdateItemList("")
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void ComportamentoModelloEventoSelection.ButtonAnnulla()
{
  this.close(...)
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void ComportamentoModelloEventoSelection.showForm(
  IDForm callerForm // Write a comment for this parameter or press backspace to delete this comment
)
{
  ModelloEventoComportamentoSelection mecs = new()
  comportamentoselectionpanel.setDocument(mecs, true)
   
  this.CallerForm = callerForm
   
  this.show(Modal)
}


// ──────────────────────────────────

// ************************************************************************
// Event raised when a form sends a message using the SendMessage procedure
// ************************************************************************
event FunzioniList.OnSendMessage(
  string Message // Indicates the name of the message
  IDForm Sender  // Identifies the form that sent the message. IDForm type object.
  IDDocument Doc // Optional. Document associated with the message.
  string Par1    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par2    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par3    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par4    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
)
{
  if (Message == "BringToFront")
  {
    this.bringToFront()
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void FunzioniList.ShowForm()
{
  Search.SearchString = ""
  this.show(...)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void FunzioniList.NewFunzione()
{
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void FunzioniList.OpenFunzioniOptionForm()
{
  MainPageFormInstanceFactory.AssegnaRuoli(TabelleFunzioni)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void FunzioniList.EditFunzione()
{
  if (FunzioniList.IDFUNZIONE > 0)
  {
    Funzione selectedFunzione = Funzione.getFromDB(FunzioniList.IDFUNZIONE, ...)
    if (selectedFunzione)
    {
      FunzioniDetails fd = new()
       
      fd.showForm(selectedFunzione, this)
    }
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void FunzioniDetails.showForm(
  Funzione funzione // Write a comment for this parameter or press backspace to delete this comment
  IDForm caller     // 
)
{
  this.Funzione = funzione
  this.FunzioneMainModuleFormHelper = MainModuleFormHelper.create(funzione, CommonMainModuleTabbedView.IDForm(), this)
  this.setObjectTag("caller", caller)
  this.show(...)
  this.FunzioneMainModuleFormHelper.updateCaptionInMainForm("")
  this.FunzioneMainModuleFormHelper.initializeAllTabbedViewSubForms()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void FunzioniDetails.Back()
{
  DevTools.ToBeReviewed("to be made common")
   
  Funzione funzione = this.Funzione
  boolean docIsModified = funzione.isModified(...)
  boolean formShouldBeClosed = true
  boolean rollbackChanges = false
   
  if (docIsModified)
  {
    int i = Qualibus.messageConfirmEx("Ci sono modifiche non ancora salvate, vuoi davvero uscire?", "Sì;No")
    if (i == null)
      return 
     
    if (i == 1)
    {
      formShouldBeClosed = true
      rollbackChanges = true
    }
    else 
    {
      formShouldBeClosed = false
    }
  }
   
  if (rollbackChanges)
  {
    funzione.restoreOriginal()
  }
   
  if (formShouldBeClosed)
  {
    this.close(true)
     
    IDForm caller = this.getObjectTag("caller")
    caller.bringToFront()
    SearchFilterIMDBInteractions.initializePanelSearchQueriesRuntimeFilters(..., Funzioni)
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void FunzioniDetails.Save()
{
  this.FunzioneMainModuleFormHelper.handleSave()
}


// ──────────────────────────────────



// ──────────────────────────────────

// *****************************************************
// Raised by the panel when the user double clicks on it
// *****************************************************
event IndicatoriList.Indicators.OnMouseDoubleClick(
  int:mouseButtons Button // Specifies which mouse button has been pressed. Refer also to the MouseButtons value list
  int X                // X position in pixels relative to the panel in which the mouse was clicked
  int Y                // Y position in pixels relative to the panel in which the mouse was clicked
  int XB               // X position in pixels relative to the browser in which the mouse was clicked
  int YB               // Y position in pixels relative to the browser in which the mouse was clicked
  int Column           // Index of the field that was clicked (-1 if the click occurred outside the fields)
  int Row              // Row clicked, from 0 to VisibleRows -1. This is -1 if the click occurred outside the fields or on the caption of the column or field
  inout boolean Cancel // Can be set to True to prevent the default action associated with the click from being run, such as execution of the field activation object.
)
{
  if (Row > 0 and Column != -1)
  {
    this.edit()
  }
}


// ──────────────────────────────────

// ***************************************************************************
// Event raised by the panel when the user rearranges the columns in the list.
// ***************************************************************************
event IndicatoriList.Indicators.OnReorderColumn(
  int SourceField // An integer representing the panel field that has been dragged & dropped. It should be compared with the Me property of the panel field.
  int TargetField // An integer representing the target field of the drag & drop operation. It should be compared with the Me property of the panel field. The dragged field is inserted just before the target field taking the drop.
)
{
  Qualibus.GridSettingsTemp = Indicators.getPanelConfiguration()
}


// ──────────────────────────────────

// ***********************************************************************
// Event raised by the panel when the data in the active panel row changes
// ***********************************************************************
event IndicatoriList.Indicators.OnChangeRow()
{
  this.Quickview()
}


// ──────────────────────────────────

// ***********************************************
// Event raised to the form when loading in memory
// ***********************************************
event IndicatoriList.Load()
{
  Search.Searchstring = ""
  Indicators.collapsable = false
  Indicators.collapsed = false
   
   
  if (Qualibus.GridSettingsTemp != "")
  {
    Indicators.setPanelConfiguration(Qualibus.GridSettingsTemp)
  }
  Indicators.listQBE = Row
  Indicators.caption = ""
   
  QuickViewIndicatordetail.visible = false
}


// ──────────────────────────────────

// ************************************************************************
// Event raised when a form sends a message using the SendMessage procedure
// ************************************************************************
event IndicatoriList.OnSendMessage(
  string Message // Indicates the name of the message
  IDForm Sender  // Identifies the form that sent the message. IDForm type object.
  IDDocument Doc // Optional. Document associated with the message.
  string Par1    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par2    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par3    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
  string Par4    // Optional. Parameter associated with the message; can be of any type (except object or generic document).
)
{
  if (Message == "BringToFront")
  {
    this.bringToFront()
  }
  if (Message == "refreshQuery")
  {
    Indicators.refreshQuery()
  }
   
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void IndicatoriList.formShow()
{
  this.show(...)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void IndicatoriList.edit()
{
  if (Indicators.IdIndicator > 0)
  {
    Indicator i = Indicator.getFromDb(Indicators.IdIndicator)
    IndicatorDetailForm.showForm(i, this)
  }
   
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void IndicatoriList.Quickview()
{
  if (Indicators.IdIndicator > 0)
  {
    Indicator indicator = Indicator.getFromDb(Indicators.IdIndicator)
    QuickViewIndicatordetail.setDocument(indicator, ...)
    QuickViewIndicatordetail.visible = true
    IndicatoriDescriptionpanel.LabelDescriptionIndicator.caption = indicator.Description
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void IndicatoriList.ButtonNuovo()
{
  Indicator i = Indicator.createEmpty()
  IndicatorDetailForm.showForm(i, this)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void IndicatoriList.Options()
{
  UITools.displayNotImplementedMessage()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void UserOptionsMainForm.showForm()
{
  // hide option not available for non admin users
  if (!(QappCore.Loggeduser.isAdministrator()))
  {
    QvmManagementForm.visible = false
  }
   
  this.show(Modal)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public static void UICustomizationHelper.performUiCustomizationWithJavascript()
{
  Qualibus.executeOnClient("*attachHomeLink();")
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void MainMenuHandler.handleClickOnMenuCommand(
  IDCommand Command // 
)
{
  int mainId = toInteger(SH.leftUpToDelimiter(Command.code, ":", ...))
  string subId = SH.rightUpToDelimiter(Command.code, ":", ...)
  if (subId == QappSpecificInfo)
  {
    this.handleQapp(mainId)
  }
  else 
  {
    this.handleNotQappClick(Command, mainId, subId)
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void MainMenuHandler.handleApplicationManager()
{
  if (QappCore.Loggeduser.isAdministrator())
  {
    boolean applicationManagerAlreadyOpened = false
    for (int i = 0; i < Qualibus.openFormsCount(); i = i + 1)
    {
      IDForm idf = Qualibus.getOpenForm(i)
      if (OpzioniMainPageForm.isMyInstance(idf))
      {
         OpzioniMainPageForm mpf1 = cast(idf)
         MainPageFormConfiguration mpfc = (MainPageFormConfiguration)mpf1.getObjectTag("subform")
         if (mpfc)
         {
           if (ApplicationsManagerConfiguration.isMyInstance(mpfc))
           {
             applicationManagerAlreadyOpened = true
             mpf1.bringToFront()
             break 
           }
         }
      }
    }
     
    if (applicationManagerAlreadyOpened == false)
    {
      MainPageFormInstanceFactory.AssegnaRuoli(ApplicationsManager)
    }
  }
  else 
  {
    Qualibus.messageBox("Solo gli utenti amministratori possono accedere a questo form")
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public IDForm MainMenuHandler.handleEventi(
  string subID // 
)
{
  IDForm eventiFormScmInstance = EventiList.newInstance(...)
  eventiFormScmInstance.sendMessage("SHOW_FOR_SUB_ID", null, subID, ...)
  return eventiFormScmInstance
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void MainMenuHandler.handleQapp(
  int mainID // 
)
{
  int IdApplicazioni = toInteger(mainID)
  NGTAPPLICAZIONI ngtapplicazioni = NGTAPPLICAZIONI.getFromDb(IdApplicazioni)
  Qualibus.openDocument(ngtapplicazioni.WEBURL, ...)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void MainMenuHandler.handleNotQappClick(
  IDCommand Command   // 
  int:kordapp kordapp // 
  string subId        // 
)
{
  // this method is fire also for Opzioni so we make sure that we initialize the filters only when it is a main module
  if (kordapp != 0)
  {
    SearchFilterIMDBInteractions.initializePanelSearchQueriesRuntimeFilters(..., kordapp, toInteger(subId))
  }
  IDForm openForm = new()
  switch (kordapp)
  {
    case ClientiFornitori:
      CliforList.formShow()
      openForm = CliforList.IDForm()
    break
    case Eventi:
      openForm = this.handleEventi(subId)
    break
    case Personale:
      PersonaleList.formShow()
      openForm = PersonaleList.IDForm()
    break
    case Calendar:
      Calendar.showForm()
      openForm = Calendar.IDForm()
    break
    case Documenti:
      Documenti.showForm()
      openForm = Documenti.IDForm()
    break
    case ApplicationsManager:
      this.handleApplicationManager()
    break
    case Funzioni:
      FunzioniList.ShowForm()
      openForm = FunzioniList.IDForm()
    break
    case Indicatori:
      IndicatoriList.show(...)
      openForm = IndicatoriList.IDForm()
    break
    default:
      if (kordapp > 0)
      {
         UITools.displayNotImplementedMessage()
      }
    break
  }
   
  openForm.caption = Command.caption
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public static void FormToolAutomation.setupPanelsCommands(
  IDForm Form // 
)
{
  if (Form and Form.getPanelsCount() > 0)
  {
    for (int i = 0; i < Form.getPanelsCount(); i = i + 1)
    {
      IDPanel idp = Form.getPanel(i)
      if (idp)
      {
         idp.setCommandEnabled(Update, false)
         idp.setCommandEnabled(Find, false)
         idp.setCommandEnabled(Search, false)
         idp.setCommandEnabled(Refresh, false)
         idp.setCommandEnabled(Cancel, false)
         idp.setCommandEnabled(Lookup, false)
//         idp.setCommandEnabled(EditBlob, false)
//         idp.setCommandEnabled(DeleteBlob, false)
//         idp.setCommandEnabled(NewBlob, false)
//         idp.setCommandEnabled(SaveBlob, false)
         idp.setCommandEnabled(PrintBook, false)
//         idp.setCommandEnabled(Attach, false)
         idp.setCommandEnabled(Export, false)
         idp.setCommandEnabled(Navigate, false)
         idp.setCommandEnabled(GroupPanel, false)
         idp.collapsable = false
//         idp.listQBE = No
      }
    }
  }
}


// ──────────────────────────────────

// *****************************************
// this procedure prepares the menu right up
// *****************************************
public static void MenuNavbar.prepareMenuNavBar()
{
  User.tooltip = QappCore.Loggeduser.Personale.getDescription()
  Profile.caption = "{{icon-fa-regular fa-circle-user}} Profilo di " + QappCore.Loggeduser.Personale.getDescription()
  MenuNavbar.computeUserCaption()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public static void MenuNavbar.computeUserCaption()
{
  Personale p = QappCore.Loggeduser.Personale
  if (p.FOTO != null)
  {
    string filename = toString(p.IDDIPENDENTE) + "_loggeduser_resource.jpg"
    string fileFullPath = Qualibus.tempPath + FH.getSeparator() + filename
    if (!(fileExists(fileFullPath)))
    {
      string loggedUserFoto = saveBlobFile(p.FOTO, Qualibus.tempPath, filename)
    }
    string loggedUserImagePath = "temp/" + filename
    User.caption = formatMessage("<img width='20' height='20' style='border-radius: 50%;'src='|1'/></img>", loggedUserImagePath, ...)
  }
  else 
  {
    User.caption = QappCore.Loggeduser.Personale.getInitials()
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public static QWCommandHandler QWCommandHandler.getInstance()
{
  if (Qualibus.QWCommandHandler != null)
  {
    return Qualibus.QWCommandHandler
  }
  else 
  {
    QWCommandHandler qwch = new()
    qwch.init()
    return qwch
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void QWCommandHandler.HandleCommand(
  string Command // 
)
{
  switch (Command)
  {
    case "HOME":
      this.manageCalendarCommand()
    break
    case "CLOSE_TAB":
      this.manageCloseTabsCommand()
    break
    case "OPEN_MODULE":
      this.manageOpenModuleCommand()
    break
    case "KILL":
      this.manageKillCommand()
    break
    case FIRSTRUN:
    case FIRSTRUNSILENT:
      boolean silent = Command == FIRSTRUNSILENT
      OnCommandHandler.doFirstRun(silent)
    break
    case VERSION:
      OnCommandHandler.doDisplayVersion()
    break
    case copyUrlButtonClicked:
      // quick link to debug (adapt it): http://127.0.0.1:1309/Qualibus/Qualibus aspx?CMD=copyUrlButtonClicked&ID_MODELLO=961
       
      for (int i = 0; i < Qualibus.openFormsCount(); i = i + 1)
      {
         IDForm idf = Qualibus.getOpenForm(i)
         idf.close(true)
      }
       
      int idModello = toInteger(Qualibus.getURLParam("ID_MODELLO"))
      int idClasse = toInteger(Qualibus.getURLParam("ID_CLASSE"))
      OnCommandHandler.doCopyUrlButtonClicked(idModello, idClasse)
    break
    case startEventoWizard:
      for (int i = 0; i < Qualibus.openFormsCount(); i = i + 1)
      {
         IDForm idf = Qualibus.getOpenForm(i)
         idf.close(true)
      }
      string INFO = Qualibus.getURLParam("INFO")
      string AUTH = Qualibus.getURLParam("AUTH")
      OnCommandHandler.doStartEventoWizard(INFO, AUTH)
    break
    case TEST_LDAP:
      for (int i = 0; i < Qualibus.openFormsCount(); i = i + 1)
      {
         IDForm idf = Qualibus.getOpenForm(i)
         idf.close(true)
      }
      string TOKEN = Qualibus.getURLParam("TOKEN")
      OnCommandHandler.doTestLDAP(TOKEN)
    break
    case DISPLAY_PUBLIC_INFO:
      string TOKEN = Qualibus.getURLParam("TOKEN")
      int idEvento = toInteger(Qualibus.getURLParam("ID_EVENTO"))
      OnCommandHandler.doDisplayPublicInfo(TOKEN, idEvento)
    break
    case SEARCH_PUBLIC_INFO:
      string GUID = Qualibus.getURLParam("CODE")
      int idModello = toInteger(Qualibus.getURLParam("MODELLO_ID"))
      OnCommandHandler.doSearchPublicInfo(GUID, idModello)
    break
  }
   
  UIBusinessLogic.RedirectUrl = Qualibus.getURLParam("REDIRECT_URL")
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void QWCommandHandler.manageCalendarCommand()
{
  if (Calendar.isOpen())
  {
    Calendar.bringToFront()
  }
  else 
  {
    Calendar.showForm()
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void QWCommandHandler.manageCloseTabsCommand()
{
   
  int index = toInteger(Qualibus.getURLParam("INDEX"))
  int openFormsCount = Qualibus.openFormsCount()
  for (int i = 0; i < openFormsCount; i = i + 1)
  {
    // current form must be closed if index from the end is ok (0 becomes 4, 1 becomes 3, ...)
    int currentFormMustBeClosed = index = openFormsCount - 1 - i
    if (currentFormMustBeClosed)
    {
      IDForm idf = Qualibus.getOpenForm(i)
      Qualibus.DTTLogMessage(formatMessage("closing form |1 i=|2", idf.caption, i, ...), ...)
      idf.close(true)
    }
  }
}


// ──────────────────────────────────

// *****************************************************************************************************************************************************************************************************
// in case we are stuck (like when a form popups and there is no close button, it happen with subforms opened as forms) we can go back to login simply without rebuilding or it can happen in production
// *****************************************************************************************************************************************************************************************************
public void QWCommandHandler.manageKillCommand()
{
  Qualibus.exit("???")
}


// ──────────────────────────────────

// ************************************************************
// manages the OPEN_MODULE command, works both when the user is
// already logged in and when AUTH token login is needed
// ************************************************************
public void QWCommandHandler.manageOpenModuleCommand()
{
  string kordAppParam = Qualibus.getURLParam("KORDAPP")
  string mainIdParam = Qualibus.getURLParam("MAIN_ID")
   
  Qualibus.DTTLogMessage(formatMessage("OPEN_MODULE: KORDAPP=|1 MAIN_ID=|2", kordAppParam, mainIdParam, [par3], [par4], [par5]), [Number], DTTInfo)
   
  if (kordAppParam == "" or mainIdParam == "")
  {
    Qualibus.DTTLogMessage("OPEN_MODULE: missing KORDAPP or MAIN_ID", [Number], DTTError)
    return 
  }
   
  Qualibus.QWCommandHandler.PendingOpenModuleKordapp = toInteger(kordAppParam)
  Qualibus.QWCommandHandler.PendingOpenModuleMainId = toInteger(mainIdParam)
   
  boolean userIsLoggedIn = QappCore.Loggeduser.IDUTENTE > 0
  if (userIsLoggedIn)
  {
    this.OpenModuleDirectly()
  }
  else 
  {
     
    // else: not logged in, AfterLogin will pick up the tags after AUTH
     
  }
}


// ──────────────────────────────────

// ********************************************************
// reads OPEN_MODULE tags and opens the correct detail form
// directly without menu, consuming the tags after use
// ********************************************************
public void QWCommandHandler.OpenModuleDirectly()
{
  int:kordapp kordApp = Qualibus.QWCommandHandler.PendingOpenModuleKordapp
  int mainId = Qualibus.QWCommandHandler.PendingOpenModuleMainId
   
  // after reading the pending values we clear them
  Qualibus.QWCommandHandler.clearPendingValues()
   
  Qualibus.DTTLogMessage(formatMessage("openModuleDirectly: kordApp=|1 mainId=|2", decode(kordApp, kordapp), mainId, ...), ..., DTTInfo)
   
  MainModule mm = MainModule.getFromDBByKordApp(kordApp, mainId)
   
  if (mm == null)
  {
    Qualibus.DTTLogMessage(formatMessage("openModuleDirectly: could not load kordApp=|1 mainId=|2", decode(kordApp, kordapp), mainId, ...), ..., DTTError)
    return 
  }
   
  IDForm openedForm = DetailFormOpener.openDetailFormOfMainModule(mm)
  if (openedForm != null)
  {
    openedForm.bringToFront()
  }
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void QWCommandHandler.clearPendingValues()
{
  PendingOpenModuleMainId = null
  PendingOpenModuleKordapp = null
}


// ──────────────────────────────────

// ***********************************************************************************************************
// returns a parameter, given a name. it returnes the overridden version if found, otherwise the url parameter
// ***********************************************************************************************************
public string QWCommandHandler.getParam(
  string paramName // 
)
{
  string result = ""
  if (OverrideParams != null)
  {
    string overrideValue = OverrideParams.getValue(paramName)
    result = overrideValue
  }
  else 
    result = Qualibus.getURLParam(paramName)
   
  return result
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void QWCommandHandler.HandleCommandWithParameters(
  string Command           // 
  IDMap overrideparameters // 
)
{
  OverrideParams = overrideparameters
  this.HandleCommand(Command)
  OverrideParams = null
}


// ──────────────────────────────────

// *****************************************************
// opens the module directly if there are pending values
// can be called both from Initialize and AfterLogin
// *****************************************************
public void QWCommandHandler.openModuleIfPending()
{
  if (PendingOpenModuleKordapp > 0)
  {
    this.OpenModuleDirectly()
  }
}


// ──────────────────────────────────

// ***************************************************************
// Open the specific detail form for the class passed as parameter
// ***************************************************************
public static IDForm DetailFormOpener.openDetailFormOfMainModule(
  MainModule mm // 
)
{
  IDForm openedForm = null
   
  if (mm == null)
  {
    Qualibus.DTTLogMessage("can't open form if main module is null", ..., DTTError)
    return openedForm
  }
   
  int kordApp = mm.getKordApp()
  int mainId = mm.getMainID()
   
  Qualibus.DTTLogMessage(formatMessage("Open detail form for kordapp '|1' and id '|2'", kordApp, mainId, ...), ...)
   
  switch (kordApp)
  {
    case Personale:
      Personale p = cast(mm)
      PersonaleDetail pd = PersonaleDetail.newInstance(...)
      pd.formShow(p, null)
      openedForm = pd
    break
    case ClientiFornitori:
      Clifor c = cast(mm)
      CliforDetail cd = CliforDetail.newInstance(...)
      cd.formShow(c, null)
      openedForm = cd
    break
    case Eventi:
      Evento e = cast(mm)
      EventiDetail ed = EventiDetail.newInstance(...)
      ed.formShow(e, null, false)
      openedForm = ed
    break
    case ModelliEventi:
      ModelloEvento me = cast(mm)
      ModelloEventoDetail med = ModelloEventoDetail.newInstance(...)
      med.formShow(me, null)
      openedForm = med
    break
    case Funzioni:
      Funzione funz = cast(mm)
      FunzioniDetails funzDetail = FunzioniDetails.newInstance(...)
      funzDetail.showForm(funz, null)
      openedForm = funzDetail
    break
    case Messaggi:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Rubrica:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Documenti:
      DevTools.ToBeReviewed("opening documenti should open documenti focusing on the correct folder + document")
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case TabelleDocumenti:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case TabelleEventi:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case AltreAnagrafiche:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Interventi:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case TabelleAltreAnagrafiche:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Checklist:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Progetti:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case TabelleProgetti:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Privati:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case TabellePersonale:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case TabelleClientiFornitori:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case TabelleFunzioni:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Articoli:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case TabelleArticoli:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case TabellePrivati:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Link:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Cruscotti:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case ApplicationsManager:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case TabelleGenerali:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Calendar:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Organigrammi:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Utenti:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case RegistrazioneProgetti:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    case Indicatori:
      Qualibus.DTTLogMessage("NOT YET IMPLEMENTED", ..., DTTError)
    break
    default:
      Qualibus.DTTLogMessage("NOT VALID KORDAPP", ..., DTTError)
    break
  }
  return openedForm
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Qualibus.computeMainMenuCommands()
{
  Qualibus.MenuManager = MenuManager.create()
  Qualibus.MenuManager.createMainMenu(MainMenu.IDCommand(), QappCore.Loggeduser)
  MainMenu.expanded = true
   
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public MenuManager Qualibus.getQualibusWebMenuManager()
{
  return Qualibus.MenuManager
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Qualibus.ExecuteCustomizationJs()
{
  ExecuteCustomizationJs.enabled = false
   
  UICustomizationHelper.performUiCustomizationWithJavascript()
   
  // trick to auto hide menu when logging in from mobile (exposed is a boolean to know if in mobile or desktop size)
  X.executeOnClient("*let el = Client.eleMap[Client.mainFrame.wep.mainContainerConf.id]; if (!el.exposed)  Client.mainFrame.wep.commandList?.toggleMenu(false);")
   
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Qualibus.Debug()
{
  Qualibus.DTTOpenDebug(...)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Qualibus.OpenProfile()
{
  Qualibus.messageBox("still not supported")
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Qualibus.changeLoggedUserPassword()
{
  ChangePasswordForm.showFor(QappCore.Loggeduser, No, No)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Qualibus.InfoVersion()
{
   
  VersionInfo qcvi = new()
  string QappCoreVersion = qcvi.getNamedPropertyValue("version")
  string QualibusWebVersion = Qualibus.QualibusWebVersion
  string infoVersionMessage = formatMessage("Qualibus Web versione: |1 - QappCore versione: |2", QualibusWebVersion, QappCoreVersion, ...)
  X.MessageBox(infoVersionMessage, ...)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Qualibus.OpenUserOptionsForm()
{
  UserOptionsMainForm uomf = UserOptionsMainForm.newInstance(Modal, ...)
  uomf.showForm()
}


// ──────────────────────────────────

// **********************************************************************************************
// this method simply delegates to documento object to download and collects and shows the errors
// **********************************************************************************************
public void Qualibus.handleDocumentDownload(
  Documento documento // 
)
{
   
  if (documento != null)
  {
    string errorMessage = ""
     
    documento.openInBrowser(false, errorMessage)
     
    if (errorMessage != "")
      Qualibus.messageBox(errorMessage)
  }
}


// ──────────────────────────────────

// ****************************************************************************************************************************************************************************
// if one way conversion of rtf to html is still not copmleted we display the form that shows the progress and set to true the in out parameter only in case conversion is done
// ****************************************************************************************************************************************************************************
private void Qualibus.displayOneWayUpgraderProgressFormIfNeeded(
  inout boolean proceedWithAfterLogin // 
)
{
  OneWayUpgrader rtfToHtmlUpgraderInstance = OneWayUpgrader.getRtfToHtmlInstance()
  OneWayUpgrader xmlUpgraderInstance = OneWayUpgrader.getXmlToDiagramInstance()
   
  boolean rtfInProgress = rtfToHtmlUpgraderInstance and rtfToHtmlUpgraderInstance.dataConversionNeedsToBePerfomed()
  boolean xmlInProgress = xmlUpgraderInstance and xmlUpgraderInstance.dataConversionNeedsToBePerfomed()
   
  if (rtfInProgress or xmlInProgress)
  {
    OneWayUpgraderProgressForm.showForm()
    proceedWithAfterLogin = false
  }
  else 
  {
    proceedWithAfterLogin = true
  }
}


// ──────────────────────────────────



// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Qualibus.initializeQualibusWebGlobalVariables()
{
  Qualibus.QWCommandHandler = QWCommandHandler.getInstance()
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
private void Qualibus.initializeQappCoreGlobalVariables()
{
  QappCore.InMobileDevice = find(lower(Qualibus.userAgent()), "android", ...) > 0 or find(lower(Qualibus.userAgent()), "iphone", ...)
}


// ──────────────────────────────────

// ****************************************
// Describe what this procedure is used for
// ****************************************
public void Qualibus.handlePendingCommandFromCookiesIfNeeded()
{
  IDMap pendingCommand = CookieHelper.readPendingCommand()
  if (pendingCommand == null)
    return 
   
  // consume immediately to avoid loops
  CookieHelper.clearPendingCommand()
   
  string command = pendingCommand.getValue("command")
  string pendingToken = pendingCommand.getValue("token")
   
  int:kordapp kordapp = toInteger(pendingCommand.getValue("kordapp"))
  int mainid = toInteger(pendingCommand.getValue("mainid"))
   
  if (command != "OPEN_MODULE")
  {
    Qualibus.DTTLogMessage(formatMessage("unexpected pending command |1, ignored", command, ...), ..., DTTError)
    return 
  }
   
  if (pendingToken == "")
  {
    QappCore.setLoginMessageForNextSession("token mancante nei cookie pendenti, effettuare il login manualmente")
    Qualibus.exit("???")
  }
   
  // authenticate using the dedicated pending-command token generated during user switch
   
  boolean isValidToken = false
  Utente u = LoginToken.authenticateUserWithToken(pendingToken, false, isValidToken)
  if (!(isValidToken))
  {
    QappCore.setLoginMessageForNextSession("Utente non trovato, effettuare il login manualmente")
    Qualibus.exit("???")
  }
   
  QappCore.Loggeduser = u
  Qualibus.userRole = Administrator
  CookieHelper.SaveLastLoggedUsrIdCookie(u.IDUTENTE)
   
  // set pending module values; AfterLogin will open the form after menu/calendar are ready
  Qualibus.QWCommandHandler.PendingOpenModuleKordapp = kordapp
  Qualibus.QWCommandHandler.PendingOpenModuleMainId = mainid
}
