<type>documentation</type>
<domain>scripting</domain>
<id>arginfo</id>
<title>Argument Collection</title>
<date>$Date$</date>
<version>$Revision$</version>
<product>per+</product>

Commands that are defined in scripts can take arguments, optionally with a default value.
Wing can collect any missing arguments for a command invocation by interacting with the
user in a dialog or, in some `keyboard personalities <ref:custom/keyboard-personalities>`__,
in the status area at the bottom of the IDE window.

By default, Wing derives the labels to use for arguments from the argument name and
assumes that the argument being collected is a string.  When this is not the case,
argument type can be specified by setting the ``arginfo`` function attribute on the
script function that defines the command. This uses the ``CArgInfo`` from ``wingapi.py``
and the ``datatype`` and ``formbuilder`` modules from Wing's internals, as documented
below.

Example
-------

The following sets up two arguments, one that is a filename, and another that allows
selecting from a popup menu:

.. python::

  import wingapi
  from wingutils import datatype
  from guiutils import formbuilder
  
  def test_arg_entry(filename, word):
    wingapi.gApplication.ShowMessageDialog('Choice {}'.format(word), "You chose: {}".format(filename))
  
  _choices = [
    ("Default", None), 
    None, 
    ("One", 1), 
    ("Two", 2), 
    ("Three", 3)
  ]
  
  test_arg_entry.arginfo = {
    'filename': wingapi.CArgInfo(
      "The filename to enter",               # The tooltip shown to use over this field
      datatype.CType(''),                    # The data type is string
      formbuilder.CFileSelectorGui(),        # Use a file selection field to collect the value
      "Filename:"                            # The field label
      ),
    'word': wingapi.CArgInfo(
      "The word to enter",                   
      datatype.CType(''),            
      formbuilder.CPopupChoiceGui(_choices), # Use a popup menu to collect this value
      "Word:"
    )
  }

CArgInfo
--------

The arguments used to instantiate a ``CArgInfo`` instance for the ``arginfo``
function attribute are:

**doc** sets the documentation string for the argument.

**type** sets the data type, using one of the classes descended from
``wingutils.datatype.CTypeDef``. See below for the most commonly used ones.

**formlet** sets the type of GUI formlet to use to collect the argument from the user.
This is one of the classes descended from ``wingutils.formbuilder.CDataGui`` See below
for the most commonly used ones.

**label** sets the label to use for the argument when collected from the user. When this
argument is omitted, the label is built from the function name with ``cmdname.replace('_',
' ').title()``.

Commonly Used Types
-------------------

The following classes in ``wingutils.datatype`` cover most cases needed for scripting:

**CBoolean** specifies a boolean.  The constructor takes no arguments.

**CType** specifies the type matching one of the parameters sent to the constructor. For
example, ``CType("")`` is a string, ``CType(1)`` is an integer, and ``CType(1.0, 1)`` is
a float or an integer.

**CValue** restricts a value to one of those passed to the constructor. For example
``CValue("one", "two", "three")`` allows a value to be either ``"one"``, ``"two"``, or
``"three"``.

**CRange** specifies a numeric range between the first and second argument passed to the
constructor. For example, ``CRange(1, 10)`` allows a value between ``1`` and ``10``,
inclusive.
  
Additional types are defined in ``src/wingutils/datatypes.py`` in the Wing source code,
but these are not usually needed in describing scripting arguments.

Commonly Used Interface
-----------------------

The following classes in ``guiutils.formbuilder`` cover most of the data collection
fields needed for scripting:

**CSmallTextGui** collects a short text string, with history, auto-completion, and other
options. The constructor takes the following keyword arguments, all of which are optional:

  **max_chars** sets the maximum allowed text length.  Set this to ``-1`` to allow any
  length.   Default: ``80``

  **history** is a list of strings for the history, most recent first, that is accessed 
  with the up and down arrow keys.  This may be the list or a callable that returns
  the list.  Default: ``None``

  **choices** is a list of strings with all valid choices, to use in the auto-completer
  that is shown as the user types. This may be a list or a callable that takes a fragment
  and returns all possible matches. Default: ``None``

  **partial_complete** is set to ``True`` to only complete as far as the unique match when
  the ``Tab``key is pressed for auto-completion.  When set to ``False``, all of the
  currently selected auto-completion match will be entered instead.  Default: ``True``

  **stopchars** is a string of characters that always stop partial completion. For
  example, ``'/'`` might be used to prevent completion of an entire url. Default=``''``

  **allow_only** is a list of characters allowed for input. All others are not processed.
  When this is set to ``None``, it allows all characters to be input. Default: ``None``

  **auto_select_choice** is set to ``True`` to automatically select all of the entry text
  when browsing on the auto-completer. This is used so that the entry will be erased if
  any subsequent typing occurs. Default: ``False``

  **default** is the default value to auto-enter initially.  Default: ``''``

  **select_on_focus** can be set to ``True`` to select any existing text when focus enters
  the field.  Default: ``False``

  **editable** can be set to ``False`` to display the field but to prevent editing it.  
  Default: ``True``
  
  **selection** can be set to a ``(start, end)`` tuple to select a range of text in
  the auto-entered ``default`` value.  If omitted, nothing is selected.  Default: ``None``
  
**CLargeTextGui** is an multi-line entry area for longer text strings. The constructor
takes no arguments.
  
**CBooleanGui** is a single checkbox for collecting a boolean value. The constructor
takes no arguments.

**CFileSelectorGui** is a keyboard-driven file selector with auto-completion, history, and
ability to browse using a standard file dialog. The constructor takes the following
optional keyword arguments:

  **name_type** specifies what type of file or directory is being selected:
  ``'existing-file'``, ``'existing-dir'``, ``'existing-executable-file'``, ``'new-dir'``,
  ``'new-file'``, or ``'save-as-file'``
  
  **default** is the default value to pre-fill into the field.  Default: ``''``
  
  **default_ext** specifies the default file extension to use.  Default: ``None``
  
  **filters** is a list of valid file name extensions. For example ``['py', 'pyi']`` to
  select either a ``*.py`` or ``*.pyi`` file. Default: ``None``

  **history** can be set to a list of past choices, most recent first, to traverse with
  the up and down arrow keys. Default: ``()``

  **tab_shows_completer** indicates that pressing the ``Tab`` key should show the
  auto-completer. Default: ``False``
  
  **hostname** (Wing Pro only) specifies the name of a remote host from which the file or
  directory should be selected. Default: ``''``, which indicates the local host.
  
**CPopupChoiceGui** is a popup menu to select from a range of values. The constructor
takes a list of items for the popup. Each item may be one of:

  **None** to insert a divider into the menu

  **A string** to insert that value into the menu.  The label used in the menu is derived
  from the value: ``label = str(value).replace('_', ' ').title()``

  **(value, label)** inserts the value into the menu using the given label.
  
  **(value, label, tooltip)** inserts the value into the menu using the given 
  label and displays the given tooltip when the mouse hovers over the item in the menu.
                            
**CNumberGui** is a small entry area for collecting a number.  The constructor
takes the following required arguments:
  
  **min_value** is the minimum allowable value.
    
  **max_value** is the maximum allowable value.
    
  **page_size** is the increment to use when the when scroller is used.
    
  **num_decimals** is the number of decimal places to show.  This is set to ``0`` to
  collect an integer.
  
Additional fields for collecting data are defined in ``src/guiutils/formbuilder.py`` in
the Wing source code, but these are not usually needed for scripting.


