# Program: xf
# Description: save misc stuff (almost everything :-)
#
# $Header: xfsaveMisc.tcl[2.5] Wed Mar 10 12:08:20 1993 garfield@garfield frozen $

##########
# Procedure: XFSaveBind
# Description: save bindings
# Arguments: xfOutFile - the output descriptor
#            xfW - the widget, or widget class
#            xfNoLeftOffset - don't indent output
# Returns: none
# Sideeffects: none
##########
proc XFSaveBind {xfOutFile xfW {xfNoLeftOffset 0}} {
  global xfConf

  # get list of bindings
  set xfTmpString ""
  if {$xfNoLeftOffset} {
    set xfLeftOffset ""
  } {
    set xfLeftOffset "  "
  }
  foreach xfCounter [lsort [bind $xfW]] {
    if {[XFMiscCorrectLevel bindsave [bind $xfW $xfCounter]]} {
      if {$xfConf(encloseBinding)} {
        append xfTmpString "\n${xfLeftOffset}bind $xfW $xfCounter \{[bind $xfW $xfCounter]\}"
      } {
        append xfTmpString "\n${xfLeftOffset}bind $xfW $xfCounter \"[bind $xfW $xfCounter]\""
      }
    }
  }
  if {"$xfTmpString" != ""} {
    puts $xfOutFile "${xfLeftOffset}# bindings$xfTmpString"
  }
}

##########
# Procedure: XFSaveComment
# Description: save comment
# Arguments: xfOutFile - the output descriptor
#            xfType - the comment type (file, module, proc)
#            xfName - the name (either filename, modulename, procname)
# Returns: none
# Sideeffects: none
##########
proc XFSaveComment {xfOutFile xfType xfName} {
  global env
  global tkVersion
  global xfConf
  global xfComment
  global xfVersionNr

  set xfTmpComment ""
  case $xfType in {
    {file} {
      set xfTmpComment $xfComment(file)
      regsub -all {\$programName} $xfTmpComment $xfName xfTmpComment
    }
    {module} {
      set xfTmpComment $xfComment(module)
      regsub -all {\$moduleName} $xfTmpComment $xfName xfTmpComment
    }
    {template} {
      set xfTmpComment $xfComment(template)
      regsub -all {\$templateName} $xfTmpComment $xfName xfTmpComment
    }
    {proc} {
      set xfTmpComment $xfComment(proc)
      regsub -all {\$procedureName} $xfTmpComment $xfName xfTmpComment
    }
  }
  regsub -all {\$interpreter} $xfTmpComment $xfConf(interpreter) xfTmpComment
  if {[info exists env(USER)]} {
    regsub -all {\$user} $xfTmpComment $env(USER) xfTmpComment
  }
  if {[info exists env(LOGNAME)]} {
    regsub -all {\$logname} $xfTmpComment $env(LOGNAME) xfTmpComment
  }
  if {[info exists env(HOST)]} {
    regsub -all {\$host} $xfTmpComment $env(HOST) xfTmpComment
  }
  regsub -all {\$tkVersion} $xfTmpComment $tkVersion xfTmpComment
  regsub -all {\$tclVersion} $xfTmpComment [info tclversion] xfTmpComment
  regsub -all {\$xfVersion} $xfTmpComment $xfVersionNr xfTmpComment
  regsub -all {\$magicCookie} $xfTmpComment Tcl/Tk/XF xfTmpComment
  puts $xfOutFile "$xfTmpComment"
}

##########
# Procedure: XFSaveGlobals
# Description: save global variables
# Arguments: xfOutFile - the output descriptor
#            xfSavePlain - save the output as plain tcl file
# Returns: none
# Sideeffects: none
##########
proc XFSaveGlobals {xfOutFile {xfSavePlain 0}} {
  global xfAppDefToplevels

  if {!$xfSavePlain} {
    set leftOffset "  "
    puts $xfOutFile "\n# initialize global variables"
    puts $xfOutFile "proc InitGlobals {} {"
    # make interpreter happy }
  } {
    set leftOffset ""
    puts $xfOutFile "\n# initialize global variables"
  }
  foreach xfCounter [lsort [info globals]] {
    if {[XFMiscIsXFElement $xfCounter]} {
      continue
    }
    if {[string match "xf*" $xfCounter]} {
      continue
    }
    if {"[string trim $xfCounter]" != ""} {
      global $xfCounter
      puts $xfOutFile "${leftOffset}global \{$xfCounter\}"
    
      # missing array handling by: Tim MaxKenzie
      # (sorry I could not keep my hands from your patch Tim :-)
      if {[catch "array names $xfCounter" xfResult]} {
        puts $xfOutFile "${leftOffset}set \{$xfCounter\} \{[set $xfCounter]\}"
      } {
        foreach xfCounter2 [lsort [array names $xfCounter]] {
          set xfArrayName ""
          append xfArrayName $xfCounter ( $xfCounter2 )
          puts $xfOutFile "${leftOffset}set \{$xfArrayName\} \{[set $xfArrayName]\}"
        }
      }
    }
  }
  puts $xfOutFile "\n${leftOffset}# please don't modify the following"
  puts $xfOutFile "${leftOffset}# variables. They are needed by xf."
  foreach xfCounter "autoLoadList internalAliasList moduleList preloadList symbolicName xfWmSetPosition xfWmSetSize" {
    global $xfCounter
    puts $xfOutFile "${leftOffset}global \{$xfCounter\}"
    if {[catch "array names $xfCounter" xfResult]} {
      puts $xfOutFile "${leftOffset}set \{$xfCounter\} \{[set $xfCounter]\}"
    } {
      foreach xfCounter2 [lsort [array names $xfCounter]] {
        set xfArrayName ""
        append xfArrayName $xfCounter ( $xfCounter2 )
        puts $xfOutFile "${leftOffset}set \{$xfArrayName\} \{[set $xfArrayName]\}"
      }
    }
  }
  set xfTmpValue ""
  foreach xfCounter $xfAppDefToplevels {
    if {"[info commands $xfCounter]" != "" ||
        "[info commands ShowWindow$xfCounter]" != ""} {
      append xfTmpValue "$xfCounter "
    }
  }
  puts $xfOutFile "${leftOffset}global \{xfAppDefToplevels\}"
  puts $xfOutFile "${leftOffset}set \{xfAppDefToplevels\} \{$xfTmpValue\}"
  if {!$xfSavePlain} {
    # make interpreter happy {
    puts $xfOutFile "}"
  }
}

##########
# Procedure: XFSaveMenubarTraversal
# Description: save menubar traversal code
# Arguments: xfOutFile - the output descriptor
# Returns: none
# Sideeffects: none
##########
proc XFSaveMenubarTraversal {xfOutFile} {
  global xfMisc

  if {[llength $xfMisc(menuBarTraversalList)] > 0} {
    puts $xfOutFile "\n  global tkVersion"
    puts $xfOutFile "  if {\$tkVersion >= 3.0} {"
    puts $xfOutFile "    tk_menuBar $xfMisc(menuBarTraversalList)"
    puts $xfOutFile "  } {"
    puts $xfOutFile "    tk_menus [winfo toplevel [lindex $xfMisc(menuBarTraversalList) 0]] [lrange $xfMisc(menuBarTraversalList) 1 end]"
    puts $xfOutFile "  }"
  }
}

##########
# Procedure: XFSavePack
# Description: save packing
# Arguments: xfOutFile - the output descriptor
#            xfW - the widget
# Returns: none
# Sideeffects: none
##########
proc XFSavePack {xfOutFile xfW} {

  # get list of pack elements
  set xfIgnore 0
  set xfTmpString ""
  set xfElementType 0
  foreach xfCounter [pack info $xfW] {
    if {$xfElementType == 0} {
      if {[string match "xf*" [winfo name $xfCounter]]} {
        set xfIgnore 1
      } {
        append xfTmpString " \\\n    $xfCounter"
      }
      set xfElementType 1
    } {
      if {$xfIgnore} {
        set xfIgnore 0
      } {
        append xfTmpString " {$xfCounter}"
      }
      set xfElementType 0
    }
  }
  if {"$xfTmpString" != ""} {
    puts $xfOutFile "\n  # pack widget $xfW\n  pack append $xfW$xfTmpString"
  }
}

##########
# Procedure: XFSavePackOne
# Description: save packing for one child
# Arguments: xfOutFile - the output descriptor
#            xfW - the widget
#            xfChild - the child we want to pack
#            xfSaveAsProc - this is for a procedure
# Returns: none
# Sideeffects: none
##########
proc XFSavePackOne {xfOutFile xfW xfChild {xfSaveAsProc 0}} {

  # get list of pack elements
  set xfTmpString ""
  set xfElementType 0
  set xfCurrentChld ""
  foreach xfCounter [pack info $xfW] {
    if {$xfElementType == 0} {
      if {"$xfCounter" == "$xfChild"} {
        append xfTmpString " \\\n    $xfCounter"
        set xfCurrentChld $xfCounter
        set xfElementType 1
      }
    } {
      if {"$xfCurrentChld" == "$xfChild"} {
        append xfTmpString " {$xfCounter}"
        set xfElementType 0
        break
      }
    }
  }
  if {"$xfTmpString" != ""} {
    puts $xfOutFile "  # pack widgets\n  pack append $xfW$xfTmpString"
  }
}

##########
# Procedure: XFSavePlace
# Description: save placing
# Arguments: xfOutFile - the output descriptor
#            xfW - the widget
# Returns: none
# Sideeffects: none
##########
proc XFSavePlace {xfOutFile xfW} {
  global tkVersion

  # get list of place elements
  set xfTmpString ""
  if {$tkVersion >= 3.0} {
    foreach xfCounter [place slaves $xfW] {
      if {![string match "xf*" [winfo name $xfCounter]]} {
        append xfTmpString "\n  # place\n"
        append xfTmpString "  place $xfCounter [place info $xfCounter]\n"
      }
    }
  } {
    foreach xfCounter [place dependents $xfW] {
      if {![string match "xf*" [winfo name $xfCounter]]} {
        append xfTmpString "\n  # place\n"
        append xfTmpString "  place $xfCounter [place info $xfCounter]\n"
      }
    }
  }
  if {"$xfTmpString" != ""} {
    puts $xfOutFile "$xfTmpString"
  }
}

##########
# Procedure: XFSavePlaceOne
# Description: save placing for one child
# Arguments: xfOutFile - the output descriptor
#            xfW - the widget
#            xfChild - the child we want to place
#            xfSaveAsProc - this is for a procedure
# Returns: none
# Sideeffects: none
##########
proc XFSavePlaceOne {xfOutFile xfW xfChild {xfSaveAsProc 0}} {
  global tkVersion

  # get list of place elements
  set xfTmpString ""
  if {$tkVersion >= 3.0} {
    foreach xfCounter [place slaves $xfW] {
      if {"$xfCounter" == "$xfChild"} {
        append xfTmpString "\n  # place\n"
        append xfTmpString "  place $xfCounter [place info $xfCounter]\n"
        break
      }
    }
  } {
    foreach xfCounter [place dependents $xfW] {
      if {"$xfCounter" == "$xfChild"} {
        append xfTmpString "\n  # place\n"
        append xfTmpString "  place $xfCounter [place info $xfCounter]\n"
        break
      }
    }
  }
  if {"$xfTmpString" != ""} {
    puts $xfOutFile "$xfTmpString"
  }
}

##########
# Procedure: XFSaveProc
# Description: save named procedure
# Arguments: xfOutFile - the output descriptor
#            xfProcName - the procedure name
# Returns: none
# Sideeffects: none
##########
proc XFSaveProc {xfOutFile xfProcName} {

  # get arg list for procedure
  set xfArgList [info args $xfProcName]
  set xfArguments ""
  foreach xfArg $xfArgList {
    if {[info default $xfProcName $xfArg xfDefault]} {
      append xfArguments " \{$xfArg \"$xfDefault\"\}"
    } {
      append xfArguments " $xfArg"
    }
  }
  set xfBodyList [string trimright [info body $xfProcName]]

  if {[XFMiscIsXFElement $xfProcName] ||
      ![XFMiscCorrectLevel procsave $xfBodyList]} {
    return
  }

  puts $xfOutFile "\n" 
  XFSaveComment $xfOutFile proc $xfProcName
  # write procedure
  if {[XFMiscIsXFSpecialElement $xfProcName]} {
    puts $xfOutFile "if {\"\[info procs $xfProcName\]\" == \"\"} {"
    puts $xfOutFile "proc $xfProcName {$xfArguments} {"
    if {[string index $xfBodyList 0] == "\n"} {
      puts $xfOutFile [string range $xfBodyList 1 end]
    } {
      puts $xfOutFile $xfBodyList
    }
    puts $xfOutFile "}"
    puts $xfOutFile "}"
  } {
    puts $xfOutFile "proc $xfProcName {$xfArguments} {"
    if {[string index $xfBodyList 0] == "\n"} {
      puts $xfOutFile [string range $xfBodyList 1 end]
    } {
      puts $xfOutFile $xfBodyList
    }
    puts $xfOutFile "}"
  }
}

##########
# Procedure: XFSaveRootToplevelChild
# Description: save the a child widget of .
# Arguments: xfOutFile - the output descriptor
#            xfName - the name of the window
# Returns: none
# Sideeffects: none
##########
proc XFSaveRootToplevelChild {xfOutFile xfName} {
  global xfAppDefToplevels
  global xfMisc

  set xfMisc(menuBarTraversalList) ""
  set xfMisc(specialSaveString) ""
  puts $xfOutFile "\n\n# procedure to show window $xfName"
  puts $xfOutFile "proc ShowWindow$xfName {args} {# xf ignore me 7"
  if {"[info procs StartupSrc$xfName]" != ""} {
    puts $xfOutFile "\nStartupSrc$xfName"
  }
  XFSaveWidget $xfOutFile $xfName
  XFSaveBind $xfOutFile $xfName
  XFSaveWidgetSpecial $xfOutFile $xfName
  XFSaveSubwindow $xfOutFile $xfName
  if {"[info procs MiddleSrc$xfName]" != ""} {
    puts $xfOutFile "\nMiddleSrc$xfName"
  }
  XFSavePack $xfOutFile $xfName
  XFSavePlace $xfOutFile $xfName
  XFSaveMenubarTraversal $xfOutFile
  if {[lsearch $xfAppDefToplevels $xfName] != -1} {
    puts $xfOutFile "  if {\"\[info procs XFLocalSetAppDefs\]\" != \"\"} {"
    puts $xfOutFile "    XFLocalSetAppDefs"
    puts $xfOutFile "  }"
  }
  if {"$xfMisc(specialSaveString)" != ""} {
    puts $xfOutFile "\n$xfMisc(specialSaveString)\n"
  }
  if {"[info procs EndSrc$xfName]" != ""} {
    puts $xfOutFile "\nEndSrc$xfName"
  }
  puts $xfOutFile "\n  if {\"\[info procs XFEdit\]\" != \"\"} {"
  puts $xfOutFile "    catch \"XFMiscBindWidgetTree $xfName\""
  puts $xfOutFile "    after 2 \"catch \{XFEditSetShowWindows\}\""
  puts $xfOutFile "  }"
  puts $xfOutFile "}"
}

##########
# Procedure: XFSaveShowWindow
# Description: save the show window procedure
# Arguments: xfOutFile - the output descriptor
#            xfName - the name of the window
# Returns: none
# Sideeffects: none
##########
proc XFSaveShowWindow {xfOutFile xfName} {

  set xfCounter xfShowWindow[string range $xfName 10 \
    [expr [string length $xfName]-1]]
  if {"[info globals $xfCounter]" != ""} {
    global $xfCounter
    if {[set $xfCounter] == 0} {
      set xfWinName [string range $xfCounter 13 end]
      # get arg list for procedure
      set xfArgList [info args $xfName]
      set xfArguments ""
      foreach xfArg $xfArgList {
        if {[info default $xfName $xfArg xfDefault]} {
          set xfArguments "$xfArguments \{$xfArg \"$xfDefault\"\}"
        } {
          set xfArguments "$xfArguments $xfArg"
        }
      }
      # get procedure body
      set xfBodyList [string trimright [info body $xfName]]
      puts $xfOutFile "\n\n# procedure to show window $xfName"
      puts $xfOutFile "proc $xfName {$xfArguments} {"
      if {[string index $xfBodyList 0] == "\n"} {
        puts $xfOutFile [string range $xfBodyList 1 end]
      } {
        puts $xfOutFile $xfBodyList
      }
      puts $xfOutFile "}"
      XFSaveSourceDestroyWindow $xfOutFile .$xfWinName
      XFSaveShowWindowTail $xfOutFile .$xfWinName
    }
  }
}

##########
# Procedure: XFSaveShowWindowTail
# Description: save the appendix of the show window procedure
# Arguments: xfOutFile - the output descriptor
#            xfWinName - the name of the window
# Returns: none
# Sideeffects: none
##########
proc XFSaveShowWindowTail {xfOutFile xfWinName} {

  if {"[info procs StartupSrc$xfWinName]" != ""} {
    set xfBodyList [string trimright [info body StartupSrc$xfWinName]]
    puts $xfOutFile "\nproc StartupSrc$xfWinName {args} {"
    if {[string index $xfBodyList 0] == "\n"} {
      puts $xfOutFile [string range $xfBodyList 1 end]
    } {
      puts $xfOutFile $xfBodyList
    }
    puts $xfOutFile "}"
  }
  if {"[info procs MiddleSrc$xfWinName]" != ""} {
    set xfBodyList [string trimright [info body MiddleSrc$xfWinName]]
    puts $xfOutFile "\nproc MiddleSrc$xfWinName {} {"
    if {[string index $xfBodyList 0] == "\n"} {
      puts $xfOutFile [string range $xfBodyList 1 end]
    } {
      puts $xfOutFile $xfBodyList
    }
    puts $xfOutFile "}"
  }
  if {"[info procs EndSrc$xfWinName]" != ""} {
    set xfBodyList [string trimright [info body EndSrc$xfWinName]]
    puts $xfOutFile "\nproc EndSrc$xfWinName {} {"
    if {[string index $xfBodyList 0] == "\n"} {
      puts $xfOutFile [string range $xfBodyList 1 end]
    } {
      puts $xfOutFile $xfBodyList
    }
    puts $xfOutFile "}"
  }
}

##########
# Procedure: XFSaveSubwindow
# Description: save the subwindows
# Arguments: xfOutFile - the output descriptor
#            xfParent - the parent widget
# Returns: none
# Sideeffects: none
##########
proc XFSaveSubwindow {xfOutFile xfParent} {

  if {![string match ".xf*" $xfParent] &&
      ("$xfParent" == "." || ![string match "xf*" [winfo name $xfParent]])} {
    foreach xfCounter [lsort [winfo children $xfParent]] {
      # save only scrollbars
      if {![string match ".xf*" $xfCounter] &&
          ![string match "xf*" [winfo name $xfCounter]] &&
          "[winfo class $xfCounter]" == "Scrollbar"} {
        XFSaveWidget $xfOutFile $xfCounter
        XFSaveBind $xfOutFile $xfCounter
        XFSaveWidgetSpecial $xfOutFile $xfCounter
        XFSaveSubwindow $xfOutFile $xfCounter
        XFSavePack $xfOutFile $xfCounter
        XFSavePlace $xfOutFile $xfCounter
      }
    }
    foreach xfCounter [lsort [winfo children $xfParent]] {
      # save everything except scrollbars
      if {![string match ".xf*" $xfCounter] &&
          ![string match "xf*" [winfo name $xfCounter]] &&
          "[winfo class $xfCounter]" != "Scrollbar"} {
        if {"$xfParent" == "." &&
            "[winfo class $xfCounter]" == "Toplevel"} {
          continue
        }
        XFSaveWidget $xfOutFile $xfCounter
        XFSaveBind $xfOutFile $xfCounter
        XFSaveWidgetSpecial $xfOutFile $xfCounter
        XFSaveSubwindow $xfOutFile $xfCounter
        XFSavePack $xfOutFile $xfCounter
        XFSavePlace $xfOutFile $xfCounter
      }
    }
  }
}

##########
# Procedure: XFSaveWidget
# Description: save widget
# Arguments: xfOutFile - the output descriptor
#            xfW - the widget
# Returns: none
# Sideeffects: none
##########
proc XFSaveWidget {xfOutFile xfW} {
  global xfConf
  global xfNoWidgetSave
  global xfPath

  if {"$xfW" == "."} {
    set xfClass Toplevel
  } {
    set xfClass [winfo class $xfW]
  }
  if {[lsearch $xfNoWidgetSave $xfClass] == -1} {
    if {"[info procs XFSaveWidget.$xfClass]" == ""} {
      if {[file exists "$xfPath(elements)/$xfClass"]} {
        source "$xfPath(elements)/$xfClass"
      } {
        foreach xfPathElement [split $xfPath(additionals) :] {
          if {[XFMiscIsDir $xfPathElement]} {
            if {[file exists "$xfPathElement/$xfClass"]} {
              source "$xfPathElement/$xfClass"
              break
            }
          }
        }
      }
    }
  }
  if {"[info procs XFSaveWidget.$xfClass]" != ""} {
    XFSaveWidget.$xfClass $xfOutFile $xfW
  } {
    set xfType [string tolower $xfClass]

    # what are we doing here ?
    puts $xfOutFile "\n  # build widget $xfW"

    set xfUseConfig 1
    # write widget type and path name
    case $xfType in {
      {button canvas checkbutton entry frame label listbox menu menubutton message radiobutton scale scrollbar text toplevel} {
        puts $xfOutFile "  $xfType $xfW" nonewline
        set xfUseConfig 0
      }
      {default} {
        puts $xfOutFile "  if {\[catch \"$xfType $xfW\"\]} {"
        puts $xfOutFile "    if {\"\[info procs XFEdit\]\" != \"\"} {"
        puts $xfOutFile "      XFProcError \"Unknown widget type: $xfType\""
        puts $xfOutFile "      return"
        puts $xfOutFile "    } {"
        puts $xfOutFile "      puts stderr \"Unknown widget type: $xfType\""
        puts $xfOutFile "      catch \"destroy .\""
        puts $xfOutFile "      catch \"exit 0\""
        puts $xfOutFile "    }"
        puts $xfOutFile "  }"
      }
    }

    # write options
    if {$xfUseConfig} {
      puts $xfOutFile "  $xfW config" nonewline
    }
    XFSaveWidgetResource $xfOutFile $xfW
    puts $xfOutFile ""
  }
}

##########
# Procedure: XFSaveWidgetResource
# Description: save widget resource values
# Arguments: xfOutFile - the output descriptor
#            xfW - the widget
# Returns: none
# Sideeffects: none
##########
proc XFSaveWidgetResource {xfOutFile xfW} {
  global xfConf

  foreach xfCounter [$xfW config] {
    # only handle options with 5 items per option entry
    if {[llength $xfCounter] == 5} {
      if {("[lindex $xfCounter 0]" == "-xscrollcommand" ||
           "[lindex $xfCounter 0]" == "-yscrollcommand" ||
           "[lindex $xfCounter 0]" == "-scrollcommand") &&
           "[lindex $xfCounter 4]" == "NoFunction"} {
        continue
      }
      if {("[winfo class $xfW]" == "Scale" ||
           "[winfo class $xfW]" == "Scrollbar") &&
           "[lindex $xfCounter 0]" == "-command" &&
           "[lindex $xfCounter 4]" == "NoFunction"} {
        continue
      }
      if {"[lindex $xfCounter 3]" != "[lindex $xfCounter 4]"} {
        if {$xfConf(encloseConfigure)} {
          puts $xfOutFile " \\\n    [lindex $xfCounter 0] {[lindex $xfCounter 4]}" nonewline
        } {
          puts $xfOutFile " \\\n    [lindex $xfCounter 0] \"[lindex $xfCounter 4]\"" nonewline
        }
      }
    }
  }
}

##########
# Procedure: XFSaveWidgetSpecial
# Description: save widget specific code
# Arguments: xfOutFile - the output descriptor
#            xfW - the widget
# Returns: none
# Sideeffects: none
##########
proc XFSaveWidgetSpecial {xfOutFile xfW} {
  global xfNoSpecialSave
  global xfMisc
  global xfPath

  if {"$xfW" == "."} {
    set xfClass Toplevel
  } {
    set xfClass [winfo class $xfW]
  }
  if {[lsearch $xfNoSpecialSave $xfClass] == -1} {
    if {"[info procs XFSaveSpecial.$xfClass]" == ""} {
      if {[file exists "$xfPath(elements)/$xfClass"]} {
        source "$xfPath(elements)/$xfClass"
      } {
        foreach xfPathElement [split $xfPath(additionals) :] {
          if {[XFMiscIsDir $xfPathElement]} {
            if {[file exists "$xfPathElement/$xfClass"]} {
              source "$xfPathElement/$xfClass"
              break
            }
          }
        }
      }
    }
    if {"[info procs XFSaveSpecial.$xfClass]" != ""} {
      append xfMisc(specialSaveString) [XFSaveSpecial.$xfClass $xfW]
    }
  }
}

# eof

