Command APPEDIT Foundation

Creates an Application Part to edit databases

Syntax
   APPEDIT ;
     [INTO <oAppEdit>] ;
  [ FIELDS <cFieldName,...> ] ;
  [ PARENT <oParent> ] ;
[ POSITION <pos1> [, <pos2>] ] ; 
    [ SIZE <size1> [, <size2>] [PERCENT] ] ; 
   [ TITLE <cTitle> ] ;
   [ COLOR <nForeGround> [, <nBackGround>] ] ;
    [ FONT <cFontCompoundName> ] ;
 [ HEADING <headingOptions> ] ;
 [ CAPTION <captionOptions> ] ;
[ NOACTION <nSuppress> ] ;
   [ STYLE PLAIN | 3D | FANCY | <nStyle> ] ;
  [ BITMAP <nBitmapID> [ FIT ] ] 
   [ ALIAS <cAlias> ] ;
     [ FOR <lForCondition> ] ;
   [ WHILE <lWhileCondition> ] ;
    [ SEEK <exprSeek> ] ;
 [ TRIGGER <deleteFunc> [ON] DELETE ] ;
 [ TRIGGER <insertFunc> [ON] INSERT ] ;
 [ TRIGGER <updateFunc> [ON] UPDATE ] ;
Parameters
<oAppEdit>
<oAppEdit> is the name of the memory variable that gets the AppEdit object assigned which is created by the APPEDIT command. If the INTO clause is used it must appear as the first option of the APPEDIT command. If it is not used the object is assigned to the variable appObject.
<cFieldNames,...>
The option FIELDS specifies a comma-separated list of field names to be edited in the AppEdit window. The field names can be specified as literals or as character expressions in parentheses. If particular fonts or colors should be used for single fields the APPFIELD command must be used for field specification (see there). This is also the case when calculation fields are to be displayed.
If neither the FIELDS option nor command APPFIELD is used, all fields of the current work area are displayed in the AppEdit window.
<oParent>
The option PARENT defines the parent of the AppEdit object. It is displayed in the parent window <oParent> at position POS and has the size SIZE. If the PARENT option is omitted the AppEdit window is displayed in a separate dialog window and the return value of AppDesktop() is used as parent.
<pos1> [, <pos2>]
The option POSITION positions an AppEdit window. If not specified the AppEdit window is displayed at the point {0,0} (bottom left corner of the parent).
There are three possibilities to position an AppEdit object. Depending on the data types used for <pos1> and/or <pos2> the AppEdit window can be positioned absolute or relative in its parent window. In addidion, text oriented (row, column) or graphic coordinates (x,y) may be used:
Coordinates to position an AppEdit window
<pos1> Value <pos2> Value Description
Array {nX,nY} n.a. NIL <pos1> is an array containing grafic coordinates for the AppEdit window
Numeric nRow Numeric nCol <pos1> is a numeric value used as row coordinate, and <pos2> specifies the column coordinate according to a text mode window
Key word TOP Key word TOP The AppEdit window is displayed
Key word LEFT Key word LEFT at the top, left, bottom, right
Key word BOTTOM Key word BOTTOM and/or centered within its parent,
Key word RIGHT Key word RIGHT according to the keywords used
Key word CENTER Key word CENTER for positioning
<size1> [, <size2>] [ PERCENT ]
The key word SIZE defines the size of an AppEdit window. As with POSITION, the size can be specified using graphic or text oriented coordinates. Additionaly, percentage values may be used. The next table shows different possibilities:
Coordinates used for size definition of an AppEdit window
<size1> Value <size2> Value Description
Array {nXsize,nYsize} n.a. NIL A two element array defines the size in pixel
Numeric nHeight Numeric nWidth Two numeric values specify the number of rows and columns according to a text mode window
If a numeric value is used for <size1> and/or <size2> in conjunction with the key word PERCENT, the values are interpreted as percentage of the parent window's height and/or width.
<cTitle>
<cTitle> is a character expression which is displayed in the title bar of an AppEdit window. It defaults to the alias name of the current work area.
<nForeGround> [, <nBackGround> ]
The COLOR option specifies foreground and background color for the :drawingArea of the AppEdit window. #define constants from XBP.CH or GRA.CH must be used (XBPSYSCLR_* or GRA_CLR_*).
<cFontCompoundName>
The FONT clause optionally specifies a character string defining the compound name of the font to be selected for the :drawingArea of the AppEdit window (see also the :setFontCompoundName() method of Xbase Parts).
<headingOptions>
The key word heading initiates the definition of a heading to be displayed in the AppEdit Window. The minimum requirement for <headingOptions> is a character string to be used as heading. Optionally, the COLOR clause can be used to define a foreground and shadow color, a font can be selected with FONT, and the heading can be aligned with ALIGN LEFT|CENTER|RIGHT. The complete HEADING options are:
HEADING <cHeadingText> ; 
[ COLOR <nForeGround> [, <nShadow>] ] ; 
[ ALIGN LEFT | CENTER | RIGHT ] ; 
[  FONT <cFontCompoundName> ] 
<captionOptions>
The option CAPTION defines color, font and alignment for the captions of edit controls. The complete CAPTION options are:
CAPTION ; 
[ COLOR <nForeGround> [, <nShadow>] ] ; 
[ ALIGN LEFT | CENTER | RIGHT ] ; 
[  FONT <cFontCompoundName> ] 
<nSuppress>
The key word NOACTION allows to suppress single or all default controls of an AppEdit window. Values for <nSuppress> are #define constants that must be added. The following table lists all possible constants:
Constants to suppress default controls
Constant Description
APPACTION_NOGOTOP Pushbutton "First" is suppressed
APPACTION_NOPREVIOUS Pushbutton "Previous" is suppressed
APPACTION_NONEXT Pushbutton "Next" is suppressed
APPACTION_NOGOBOTTOM Pushbutton "Last" is suppressed
APPACTION_NOINSERT Pushbutton "New" is suppressed
APPACTION_NODELETE Pushbutton "Delete" is suppressed
APPACTION_NOCANCEL Pushbutton "Cancel" is suppressed
APPACTION_NOEDIT Pushbutton "Edit" is suppressed
APPACTION_NOSEEK Pushbutton "Seek" is suppressed
APPACTION_NONAVIGATION Pushbuttons for navigation are suppressed
APPACTION_NOMODIFY Pushbuttons for editing are suppressed
APPACTION_NONE No pushbuttons are displayed
APPACTION_NOFIELDS Fields are not automatically created
<nBitmapID> [ FIT ]
The option BITMAP specifies the resource ID of a bitmap which is to be displayed in the background of an AppEdit window. Without the option FIT, the bitmap is displayed repeatedly until it has filled the entire display area. If FIT is used, the bitmap is displayed once, and scaled to the size of the display area of the AppEdit window.
3D | PLAIN | FANCY | <nStyle>
The key word STYLE defines the style, or the appearance, of an AppEdit window. Default styles are selected specifying either option 3D, PLAIN, or FANCY. Optionally, styles can be defined by adding constants listed in the next table, and using the result for <nStyle>:
Constants for style definition of an AppEdit window
Constant Description
APPSTYLE_FANCY Is equal to STYLE FANCY
APPSTYLE_3D Is equal to STYLE 3D
APPSTYLE_PLAIN Is equal to STYLE PLAIN
APPSTYLE_NOBORDER The border of the dialog window is suppressed
APPSTYLE_NOTITLEBAR The title of the dialog window is suppressed
APPSTYLE_NOFRAMECONTROLS Control elements in the title bar are suppressed (maximize, minimize button and system menu)
APPSTYLE_NOHEADING The heading of the AppEdit window is suppressed
APPSTYLE_NOSTATUS The status bar is suppressed
APPSTYLE_ACTIONICONS Pushbuttons are displayed as icons
APPSTYLE_ACTIONTEXT Pushbuttons have text captions
APPSTYLE_ACTIONTOP Pushbuttons are displayed at the top of the AppEdit window
APPSTYLE_ACTIONLEFT Pushbuttons are displayed on the left in the AppEdit window
APPSTYLE_ACTIONBOTTOM Pushbuttons are displayed at the bottom of the AppEdit window
APPSTYLE_ACTIONRIGHT Pushbuttons are displayed on the right in the AppEdit window
APPSTYLE_RAISED Frames appear in raised style
APPSTYLE_HORIZONTAL Fields are positioned horizontally row by row
<cAlias>
The option ALIAS specifies the alias name for the work area to be used for database navigation by the AppEdit object. It defaults to the current work area.
<lForCondition>
<lForCondition> is an optional logical expression defining a condition, or a code block with a logical return value. Only records for which <lForCondition> returns the value .T. (true) can be edited. This allows to edit a subset of database records.
<lWhileCondition>
<lWhileCondition> is an optional logical expression defining a condition, or a code block with a logical return value. It is evaluated after database navigation. The AppEdit window is automatically closed when <lWhileCondition> yields .F. (false).
<exprSeek>
<exprSeek> is a literal numeric expression or a code block with a numeric return value. It is evaluated after the "Seek" pushbutton is clicked. This allows to embed user defined search routines into the AppEdit window. The numeric return value of <exprSeek> must correspond to an APPOP_* #define constant (see below).
<deleteFunc> ON DELETE
<deleteFunc> is a character string with the name of a user defined function. It is called when the "Delete" pushbutton is clicked. Alternately, a code block can be specified for <deleteFunc>. The return value of the function, or code block, must correspond to an APPOP_* #define constant (see below).
<insertFunc> ON INSERT
<insertFunc> is a character string with the name of a user defined function. It is called when the "Save" pushbutton is clicked while the AppEdit window is in INSERT mode. This mode is activated by clicking the "New" pushbutton. Alternately, a code block can be specified for <insertFunc>. The return value of the function, or code block, must correspond to an APPOP_* #define constant (see below).
<updateFunc> ON UPDATE
<updateFunc> is a character string with the name of a user defined function. It is called when the "Save" pushbutton is clicked while an existing record is edited. Alternately, a code block can be specified for <updateFunc>. The return value of the function, or code block, must correspond to an APPOP_* #define constant (see below).
Description

APPEDIT is a very powerful command that allows to program standardized edit dialogs for databases in a comfortable way. It creates an object of the AppEdit class and adds Xbase Parts, which access database fields.

An AppEdit object is a container for Xbase Parts.

Although the command has many options it is easy to use. The minimum requirements to display an edit dialog are three lines of code:

USE Customer NEW 
APPEDIT 
APPDISPLAY 

These three lines open a database (USE), create an AppEdit object (APPEDIT), and display it (APPDISPLAY). The AppEdit window contains edit controls for all fields of the database. In addition, pushbuttons are included for database navigation. All other options of the APPEDIT command are used to configure the edit window in detail or to specify the fields and pushbuttons to be displayed.

Options for display
Key word Description
PARENT Defines the parent
POSITION Positions the AppBrowse window within the parent
SIZE Defines the size of the AppBrowse window
TITLE Character string to be displayed in the title bar
COLOR Defines colors for table columns
FONT Defines font for table columns
HEADING Defines colors, font and alignment of a heading
CAPTION Defines colors, font and alignment for captions
STYLE Defines display style
NOACTION Suppresses default controls
BITMAP Defines a background bitmap

The most important options for display are PARENT, STYLE, POS and SIZE.

PARENT

The key word PARENT decides whether or not an AppEdit object is displayed within its own dialog window. When the option PARENT is used, the edit window is displayed without a dialog frame within the parent window. If PARENT is not specified, the AppEdit window is created having its own dialog window. It is then displayed on the desktop (AppDesktop()).

STYLE

The option STYLE defines the appearance of an AppEdit window. The default style is 3D. Three predefined styles can be selected for an AppEdit window using key words: STYLE PLAIN, STYLE 3D and STYLE FANCY.

POS

The option POS allows to position an AppEdit window within its parent window using different units for coordinates. The units 'pixel', 'text coordinates' and the key words TOP, LEFT, BOTTOM, RIGHT, CENTER are supported. This provides maximum flexibility for positioning of an AppEdit window. Different possibilities are shown below:

POS {100,200}        // Array     => x,y coordinates in pixel 
POS 10, 20           // Numeric   => Row and column coordinates 
POS LEFT 
POS TOP,CENTER       // Key words => Default positions 

A pixel-exact positioning is achieved with a two element array containing graphic x,y coordinates (the origin of the coordinate system is bottom, left). Numeric values are interpreted as row and column text-coordinates (the origin is top, left). Using key words an AppEdit window can be placed at well defined positions. The key word LEFT means, for example, that the AppEdit is displayed on the left side of its parent window. TOP, CENTER displays it at the top and centers it horizontally.

SIZE

The option SIZE defines the size of the display area of the AppEdit window (this is equal to the size of XbpDialog:drawingArea). A two element array defines the size in x and y direction (width and height), the unit is 'pixel'. Numeric values specify the number of rows and columns according to a text-mode window. If the key word PERCENT is specified, numeric values are used as percentage to calculate width and height from the size of the parent window (range 0-100).

Options for database access

The next table list all options relevant for database access:

Key word Description
FIELDS Names of fields to be displayed
ALIAS Alias name of the work area used for navigation
FOR Condition for database records to display
WHILE Condition executed after SKIP
SEEK Expression executed by the "Seek" pushbutton
TRIGGER ON DELETE User function executed prior to DELETE
TRIGGER ON INSERT User function executed prior to APPEND BLANK
TRIGGER ON UPDATE User function executed prior to REPLACE

If database navigation is not to take place in the current work area, the alias name of the corresponding work area must be specified with the ALIAS option. The option FIELD specifies the fields to be edited in the AppEdit window. Field names must be programmed as literals or as character expressions in parentheses. If fields from multiple work areas are to be displayed, the field names must be alias referenced. Edit controls in the edit window are displayed in the same order like the fields are specified. Instead of using the FIELDS option, fields can be specified using the APPFIELD command prior to displaying the edit window with APPDISPLAY. If neither FIELDS nor APPFIELD is used the AppEdit window contains edit controls for all fields of the specified work area.

The other options for database operations are expressions, or code blocks, to be executed in case of particular database operations. Logical expressions must be used for the FOR and WHILE options. Both are evaluated after the record pointer is moved. If the FOR condition evaluates to .F. (false) the record pointer is moved until the result in .T. (true) or the end of file is reached.

Expressions for the SEEK and TRIGGER ON... options must return a numeric value that corresponds to #define constants listed in the next table:

Return values for SEEK and TRIGGER expressions
Constant Description
APPOP_PROCEED AppEdit proceeds with the database operation and refreshes the display
APPOP_IGNORE AppEdit performs no database operation and does not refresh the display
APPOP_REFRESH AppEdit performs no database operation and refreshes the display

SEEK

The SEEK expression is used to call a user defined search routine from AppEdit when the "Seek" pushbutton is clicked. If return value of the expression is APPOP_PROCEED, the AppEdit window is refreshed. Otherwise the record pointer is positioned on the record that was current before the SEEK expression was evaluated.

TRIGGER

After the key word TRIGGER a character string with the name of a user defined function, or a code block, receiving one parameter must be specified. AppEdit evaluates a trigger prior to one of the database operations Insert, Update and Delete. A one dimensional array containing the current buffers of all edit controls in the AppEdit window is passed to the function, or code block, respectively. The sequence of the values in the array is defined by the sequence of field names specified with the FIELDS option (the value for the first specified field is stored in the first array element aso.) All values have the same data type like the corresponding fields (except memo fields).

The return value of the user defined function, or the trigger code block, must be one of the above listed #define constants.

TRIGGER <...> ON DELETE

The user function, or code block, is executed when the "Delete" pushbutton is clicked. By default this results in a DELETE operation. Before the current record actually gets deleted, AppEdit evaluates the DELETE trigger. If this returns APPOP_PROCEED, the AppEdit object deletes the record and refreshes the window. The return value APPOP_IGNORE suppresses deletion, and AppEdit does nothing. The window is refreshed without deleting the record, if APPOP_REFRESH is returned. In this case the user function must perform the DELETE operation.

TRIGGER <...> ON INSERT

The user function, or code block, is executed when the "Save" pushbutton is clicked while AppEdit is in INSERT mode.

This mode is activated by the "New" pushbutton.

AppEdit appends a blank record before writing data to the database. Prior to adding a new record AppEdit evaluates the INSERT trigger. If this returns APPOP_PROCEED, the AppEdit object appends a new record and writes data from the edit controls to the corresponding database fields. The return value APPOP_IGNORE suppresses an APPEND BLANK, and AppEdit does nothing. The window is refreshed without adding a new record, if APPOP_REFRESH is returned. In this case the user function must perform the APPEND BLANK operation and must write data to the database.

TRIGGER <...> ON UPDATE

The user function, or code block, is executed when the "Save" pushbutton is clicked while AppEdit is in EDIT mode.

This mode is activated by the "Edit" pushbutton.

By default this results in REPLACE operations. Before the data from edit controls are written to the current record, AppEdit evaluates the UPDATE trigger. If this returns APPOP_PROCEED, the AppEdit object updates the record with buffered data. The return value APPOP_IGNORE suppresses the update, and AppEdit does nothing. The window is refreshed without updating the record, if APPOP_REFRESH is returned. In this case the user function must write data to the current record. It also must guarantee record locks to be set if the database is open in SHARED mode.

Examples
Programming an Edit dialog for databases using command syntax

// A modal AppEdit window is created in this example that edits 
// all fields of a database. A DELETE trigger is used to confirm 
// deletion of the current record. 

#include "Appedit.ch" 
#include "Gra.ch" 
#include "Xbp.ch" 

MEMVAR appObject 

PROCEDURE AppSys 
// Desktop remains application window 
RETURN 

PROCEDURE Main 

   USE Customer                     // Open database 

     APPEDIT ;                      // Define edit dialog 
       TITLE (CurDirectory() + "\" + Alias() + ".DBF") ; 
     HEADING "Kunden Adressen" COLOR  GRA_CLR_RED ; 
    POSITION CENTER ; 
     TRIGGER "ConfirmDelete" ON DELETE 

   APPDISPLAY                       // Display AppEdit window modal 
RETURN 

********************************* 
FUNCTION ConfirmDelete( aValues ) 

   IF Ascan( aValues, {|x| ! Empty(x) } ) == 0 
      RETURN APPOP_PROCEED          // All fields are empty 
   ENDIF                            // Delete record! 

   IF ConfirmBox( , "Do you really want to delete this record?", ; 
                    "Delete record", ; 
                    XBPMB_YESNO, ; 
                    XBPMB_QUESTION ) == XBPMB_RET_NO 

      RETURN APPOP_IGNORE           // Don't delete! 
   ENDIF 

RETURN APPOP_PROCEED                // Ok to delete 
Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.