/* Class: GotoIntelAddrDialog
   SubClass of the GotoLineDialog.  -  This class handles goto address 
   input for the Intel family.
   
 */!!

inherit(GotoAddrDialog, #GotoIntelAddrDialog, #(addrSpace
operandAddrSize
addrTypeNotSupported
addrSizeDisabled
ioSpaceDisabled), 2, nil)!!

now(class(GotoIntelAddrDialog))!!

/* call open, then customize for Memory and Dasm display:
   - disable address size control.
   - don't offer io as selection for space. */
Def openForMem(self, addrDesc, addrSize | theDlg)
{
  theDlg := new(self:Behavior);
  if theDlg
    addressSizeDisabled(theDlg);
    ioSpaceDisabled(theDlg)
  endif;
  ^init(theDlg, addrDesc, addrSize); 
}
!!

/* 3/15/1994 11:27  - PUBLIC 
  Create a GotoIntelAddrDialog object and initialize.
  NOTES:
    <addrDesc>  is the input/output address descriptor.
    <addrSize>  is the global state of operand/address Size of the parent
    window.    
*/
Def open(self, addrDesc, addrSize | theDlg)
{ 
  theDlg := new(self:Behavior);
  ^init(theDlg, addrDesc, addrSize); 
}
!!

now(GotoIntelAddrDialog)!!

/* 8/24/1994 13:03 - PUBLIC */
Def getAddrSpace(self)
{
  ^addrSpace;
}
!!

/* Disable the io space entry */
Def ioSpaceDisabled(self)
{ 
  ioSpaceDisabled := 0;
}
!!

/* Remove the "IO" selection if necessary. */
Def processAddressSpaces(self, spaceColl) 
{
  if ioSpaceDisabled  
    ^extract(spaceColl, {using(space)  asLowerCase(space) <> "io"; });
  endif;
  ^spaceColl;
}
!!

/* 6/14/1994 14:14 - PUBLIC
  Disable the address size field
*/
Def addressSizeDisabled(self)
{ 
  addrSizeDisabled := 0;
}
!!

/* 6/14/1994 14:14 - PUBLIC 
  Validate the input address if Caller wants to reject
  certain address type.
  - Caller must set the <addrTypeNotSupported> variable.
  Return: GOOD if <addrDesc> is accepted, else return nil.
*/
Def acceptInputAddr(self | addrType)
{ 
  if (addrTypeNotSupported cand 
    (addrType := getAddressType(AddressLibClass$Inst, addrDesc)) cand
    (addrType = addrTypeNotSupported)) then
    /* Popup error message */
    displayFormattedError(ErrorTextLibClass$Inst, 
       ER_ADR_TYPE_NOT_SUPPORTED, CHECK_MODE, nil, nil, nil);
    ^nil;
  endif;  
  ^GOOD;            
}
!!

/* 6/14/1994 14:14 - PUBLIC
  Caller of the GotoIntelAddrDialog class can use this method
  to disable the dialog from accepting the specified address type.
  NOTES: <addrType> is ADDR_VIRTUAL, ADDR_LINEAR, ADDR_PHYSICAL
*/
Def addressTypeNotSupported(self, addrType)
{ 
  addrTypeNotSupported := addrType;
}
!!

/* 6/2/1994 13:03 - PUBLIC */
Def getViewAddressSize(self)
{
  if addrSizeDisabled
    ^nil;
  endif;
  ^operandAddrSize;
}
!!

/* 3/15/1994 11:40  - PRIVATE
  Process command of self, any left over let the ancestor handles.
  NOTES: addrDesc is an instance variable of the parent class. 
*/
Def command(self, wp, lp | spaceTxt, addrSize)
{ 
  if ((wp == IDOK) and (high(lp) = 0)) then
    if not(spaceTxt := getCBText(self, DLG_COMBO_ADDR_SPACE)) cor
       not(addrSpace := translateAddrSpace(AddressLibClass$Inst, spaceTxt)) then
       ^nil;
    endif;  
    /* Set the user specified address space */
    setAddrSpace(AddressLibClass$Inst, addrDesc, addrSpace);
    /* Get the new operandAddrSize for caller */
    if not(addrSizeDisabled)
      if ((addrSize := asInt(sendDlgItemMessage(self, DLG_COMBO_ADDR_SIZE, 
                            CB_GETCURSEL, 0, 0))) cand (addrSize ~= LBN_ERR))   
        operandAddrSize := addrSize;
      endif;
    endif;
  endif;
  /* ancestor does the rest of the work */
  ^command(self:ancestor, wp, lp);  
}
!!

/* 3/15/1994 11:34 - PRIVATE
  init instance variables.
*/
Def init(self, newAddr, newSize)
{ 
  if not(newAddr) ^nil; endif;
  /* NOTES: addrDesc is instance variable of GotoAddrDialog class */
  addrDesc := newAddr;
  if not(addrSpace := getAddressSpace(AddressLibClass$Inst, addrDesc)) then
     addrSpace := ADDR_SPACE_DEFAULT; 
  endif;
  if not(addrSizeDisabled)
    operandAddrSize := min(newSize, ADDR_USE_AUTO);
  endif;
  /* default support all address types: 
  ** ADDR_VIRTUAL, ADDR_LINEAR, ADDR_PHYSICAL 
  */
  addrTypeNotSupported := nil;
}
!!

/* 3/15/1994 11:17 - PRIVATE
  Load the specified combo box with the items in the <txtColl>.
  Set the current selection as the specified input <selIdx> and return
  the selection index.
  Return nil if failed. 
*/
Def initComboBox(self, comboId, txtColl, selIdx)
{ 
  clearCBText(self, comboId);
  if txtColl cand (size(txtColl) > 0) then
    do (txtColl,
      {using(txtElement)
        addCBText(self, comboId, txtElement);
      }); 
    /* Set current selection and focus */  
    ^sendDlgItemMessage(self, comboId, CB_SETCURSEL, selIdx, 0L); 
  endif;
  ^nil;
}
!!

/* 3/15/1994 10:24 - PRIVATE
  Initialize the GotoIntelAddrDialog object.
*/
Def initDialog(self, wp, lp | spaceColl, txtColl, addrTxt) 
{ 
  /* Retrieve the address Spaces list from the Address Server */
  if not(spaceColl := getAddressSpaces(AddressLibClass$Inst)) cor
    not(spaceColl := processAddressSpaces(self, spaceColl)) cor
    not(initComboBox(self, DLG_COMBO_ADDR_SPACE, spaceColl, 0)) then
      /* disable the control */
      disableItem(self, DLG_COMBO_ADDR_SPACE);  
  else
    if (addrTxt := getAddrSpaceText(AddressLibClass$Inst, addrSpace)) then
      sendDlgItemMessage(self, DLG_COMBO_ADDR_SPACE, LB_SELECTSTRING, 
                        0, asciiz(addrTxt)); 
    endif;         
  endif;
  
  /* Set the operand/AddressSize */
  if (addrSizeDisabled)
    disableItem(self, DLG_COMBO_ADDR_TEXT);
    disableItem(self, DLG_COMBO_ADDR_SIZE);
  else
    txtColl := new(OrderedCollection, 3);
    add(txtColl, "Auto");
    add(txtColl, "Use16");
    add(txtColl, "Use32");
    if not(initComboBox(self, DLG_COMBO_ADDR_SIZE, txtColl, operandAddrSize)) 
      cor not(operandAddrSize) then
        disableItem(self, DLG_COMBO_ADDR_SIZE);  
    else
      sendDlgItemMessage(self, DLG_COMBO_ADDR_SIZE, LB_SELECTSTRING, 
                        0, asciiz(txtColl[operandAddrSize]));     
    endif;
  endif;
 
  /* Call ancestor to do the rest of the work */
  ^initDialog(self:ancestor, wp, lp);
}
!!