Module Data_set.pkg
1//************************************************************************
2//
3// Confidential Trade Secret.
4// Copyright 1987-1997 Data Access Corporation, Miami FL, USA
5// All Rights reserved
6// DataFlex is a registered trademark of Data Access Corporation.
7//
8//************************************************************************/
9
10//************************************************************************
11// File Name: Data_Set.Pkg
12// Creation Date: January 1, 1991
13// Modified Date: April 21, 1992
14// Author(s): Steven A. Lowe
15//
16// This module contains the Data_Set class definition.
17//************************************************************************/
18// 4/21/99 JJT Added OnConstrain support
19// 11/26/97 JJT Moved data_set_should_save into class from dfclient.pkg
20// 04/11/97 JJT Added Refind_DD_Records which is just like Refind_records
21// except it only operates on in_use DDs. Otherwise, non
22// connected not-in-use DDs clear the buffer (very bad for
23// sysfiles).
24// 11/05/96 JJT Added Set DDO_Server Message (same as Attach_Server)
25// 08/29/96 JJT Item_Find Fix, where send attach_main_File sent to server
26// 07/23/96 JJT Renamed to DataSet (Maintain Data_Set as well)
27//************************************************************************/
28// 2/26/2002 JJT - 8.2 clean up (indirect_file, local, self, etc.)
29
30#CHKSUB 2 1 // Verify the data_set subsystem.
31
32use VDFBase.pkg
33use fndmodes.pkg
34use refmodes.pkg
35//use enclient.pkg
36
37#IFDEF REPLACE_CLASS_NAME
38#ELSE
39 #COMMAND REPLACE_CLASS_NAME R R
40 #IFDEF U_!2
41 #Replace U_!1 U_!2
42 #IFSUB '!2$SC'
43 #Replace !1$SC !2$SC
44 #ENDIF
45 #IFSUB '!2$SM'
46 #Replace !1$SM !2$SM
47 #ENDIF
48 #IFSUB '!2$EM'
49 #Replace !1$EM !2$EM
50 #ENDIF
51 #ENDIF
52 #ENDCOMMAND
53#ENDIF
54
55// removed in 14.1 (These were never used)
56// Define defaults (If not previously defined)
57//define DEFAULT$SMART$FILEMODE$STATE for FALSE
58//define DEFAULT$CASCADE$DELETE$STATE for TRUE
59
60//
61//Global integer status values
62//
63define OPERATION_MODE for |VI99 //status of data-sets in application
64define OPERATION_ORIGIN for |VI108 //origin of current of data-set operation
65
66//
67//Constants for Operation_Mode global int values
68//
69define MODE_WAITING for 0 //wait-mode
70define MODE_FINDING for 1 //find-mode
71define MODE_CLEARING for 2 //clear-mode
72define MODE_CREATING for 3 //create-mode
73define MODE_SAVING for 4 //save-mode
74define MODE_DELETING for 5 //delete-mode
75define MODE_ABORTING for 6 //abort-mode
76define MODE_VALIDATING for 7 //request_validate-mode : added for VDF7
77define MODE_CLEARINGALL for 8 //clear-all mode (added in VDF8)
78
79//
80// Description
81//
82// The Data_Set class is implemented as a subclass of Entry_Client, with
83// a C language handler providing the majority of new behavior. The
84// Data_Set class is intended to be a grouping agent for data-entry objects
85// and a container for subordinate Data_Sets.
86//
87// Assumptions/Preconditions
88//
89// None.
90//
91// Exceptions
92//
93// None.
94//
95// Notes
96//
97// Syntax:
98//
99// Object <name> is a DataSet <image> {ACTION_BAR <ActionBar>} {POP_UP}
100// {RING} {MAIN_FILE <Main_File> {BY <Index>} }
101// {UPDATING <File> | <DataSetID> ... } }
102// :
103// End_Object
104//
105// Data_Sets may be used to group DEOs as well as other Data_Sets.
106// Note also that a nested (component) Data_Set automatically enforces an
107// UPDATES visibility and a RELATES TO constraint between its main_file and
108// its parent's main_file.
109//
110
111// _Data_Set class deinition, private class layer. (Extra class layer needed
112// to augment procedures defined in C class handler.)
113//
114// _Data_Set class deinition, private class layer. (Extra class layer needed
115// to augment procedures defined in C class handler.)
116//
117//Class _Data_Set is an Entry_Client ; //_Data_Set inherits from Entry_Client
118// STARTMAC dsStart ; //dsStart macro is used to handle syntax
119// 0 0 ; //default colors
120// Data_Set_Handler //C-function for base class behavior
121
122// !A [] $461 U__DATA_SET //register C messages
123
124//#IFDEF IS$WINDOWS
125Use BaseData_Set.pkg
126
127// Data_Set class definition, public class layer. (Extra class layer needed
128// to augment C-based (Constrain) procedure(s).)
129
130{ ClassType=Abstract ClassLibrary=Common }
131{ HelpTopic=DataSet }
132Class DataSet is a BaseData_Set
133
134
135 // maintain old name for the time being to maximize compatability
136 // between character mode and windows versions. Developers should be
137 // able to move DS classes back and forth without changes.
138 Replace_Class_Name Data_Set DataSet
139
140 Procedure Construct_Object //Integer Img#
141 Forward Send Construct_Object No_Image //Img#
142
143 { DesignTime=False }
144 Property Integer Constrain_File 0
145 { Category=Data }
146 { PropertyType=Boolean }
147 Property Integer Auto_Fill_State False
148 { Visibility=Private }
149 Property Integer Change_Disabled_State False
150 // RT sets this inside of Mark_components a part of old entry_client DSO behavior. Now it is never used
151 { Visibility=Private }
152 Property Integer Component_State False
153
154 // just use RT default of False & True
155 //Set Smart_Filemode_State to DEFAULT$SMART$FILEMODE$STATE
156 //Set Cascade_Delete_State to DEFAULT$CASCADE$DELETE$STATE
157 // Set Focus_Mode to NO_ACTIVATE
158 End_Procedure // Construct_Object
159
160
161 //
162 // This may be called by legacy DSO and DDO code
163 //
164 // IMPORTANT NOTE of change for 8.2:
165 // DO NOT call or augment this anymore.
166 //
167 // for sending: Find all cases of Field_main_index and change it to File_Field_Index
168 //
169 // for augmenting: In DSOs - replace Field_main_index with File_field_index
170 // In DDOs - replace Field_main_Index with Field_Index and do not pass
171 // the file parameter.
172 // See DDOs Field_index and File_field_Index for more
173 //
174 { Obsolete=True MethodType=Property }
175 function Field_Main_Index integer file integer field returns integer
176 integer dataType fldNdx retval ordr
177 move -1 to retval //field has no main index (default)
178 if file ne 0 begin
179// FIELD_DEF file field to dataType fldNdx
180 get_attribute DF_FIELD_INDEX of file field to fldNdx // main index field
181 if (fldNdx > 0 OR field = 0) move fldNdx to retval //field has main index
182 end
183 if file eq (main_file(self)) begin
184 get ordering to ordr
185 if ordr ge 0 move ordr to retval //ordering takes precedence over main index
186 end
187 function_return retval
188 end_function
189
190 // This allows packages that still use data-sets instead of DDOs to use this
191 // message syntax.
192 // Note that this will never get here if the DD class is used as
193 // it has its own handler for this. It only is called if DSOs are used in which
194 // case it calls the old message field_main_index above.
195 // DDO based objects will NEVER call this code
196 //
197 { Visibility=Private MethodType=Property }
198 function File_Field_Index integer iFile integer iField returns integer
199 function_return (Field_main_Index(self,iFile,iField))
200 end_function
201
202
203 { Visibility=Private }
204 procedure Item_Find integer eFindMode ;
205 integer iFile integer iField ;
206 integer bDoEntryUpdate integer bShowFindErr integer bDeferred
207
208 RowId riRow
209 integer iIndex
210 Handle hoServer
211 integer iSegments iSeg iSegFld iSegFldMainIndex
212 boolean bChanged bDoCheck bOk
213
214 //Get Field_Main_Index iFile iField to iIndex
215 Get File_Field_Index iFile iField to iIndex
216 If (iIndex<>-1) Begin
217 // get prior rowId before it get cleared
218 Move (GetRowID(iFile)) to riRow
219 // 'hold' buffer to prepare for entry_update
220 Set_Attribute DF_FILE_STATUS of iFile to DF_FILE_INACTIVE
221 if bDoEntryUpdate Begin
222 send Request_Entry_Update iFile 1 //entUpdt all DEOs as required
223
224 // If the buffer is cleared (no record and no changed data) then we want
225 // to do a constrained_clear which will force the buffer to get cleared
226 // according to the rules of the current constraints.
227 //Get_field_value iFile 0 to iRec
228 //Move (GetRowID(iFile)) to riRow // 12.1 moved above the set file inactive
229
230 // If there was an active record to begin with we consider this changed (not cleared)
231 If (not(IsNullRowId(riRow))) Begin
232 Move True to bChanged
233 End
234 Else Begin
235 // or, if the record was already changed or the entry_update created a change
236 // we consider this changed
237 Get_Attribute DF_FILE_CHANGED of iFile to bChanged
238 End
239
240 If not bChanged Begin
241 // if buffer is unchanged, do a constrained clear. It is unchanged if there was not
242 // active record, the record was unchanged, and the update didn't change anything.
243 Constrained_Clear eFindMode iFile by iIndex
244 End
245 Else If (eFindMode=GE or eFindMode=LE and iIndex>0) Begin
246
247 // If mode is GE or LE we need to do some extra processing. We want to clear
248 // all index segemnt fields that occur after this field in the index. This way
249 // dbList searches and find ge searches (f9) will always find the first record
250 // that matches the data in the field being searched. This was if an index like
251 // customer.name x customer.number where you had 10 identical names "john" typing
252 // john will find the first record, because customer.number will get cleared.
253 // Note we can no do this with GT or LT or you'd get stuck in fields
254
255 // check all fields for index. Once you find the iField field, clear all
256 // fields that follow it. Only do this if the other fields do not use the
257 // same index as its primary index (in which case we assume the data is intentional).
258 // This should handle most cases.
259 get_attribute DF_INDEX_NUMBER_SEGMENTS of iFile iIndex to iSegments
260 for iSeg from 1 to iSegments
261 get_Attribute DF_INDEX_SEGMENT_FIELD of iFile iIndex iSeg to iSegFld
262 If not bDoCheck begin
263 If (iSegFld=iField) ;
264 Move True to bDoCheck // marked after we find the find field in the index
265 end
266 else Begin // we get here after we've found the main field segment
267 // if main index if this segment is same as our find index, do nothing
268 Get File_Field_Index iFile iSegFld to iSegFldMainIndex
269 If (iSegFldMainIndex<>iIndex) ;
270 set_field_value iFile iSegFld to ''
271 end
272 loop
273 end
274
275 Get Which_Data_Set iFile to hoServer
276 if (hoServer AND iFile=main_file(hoServer)) ;
277 send Attach_Main_File to hoServer
278 else ;
279 attach iFile
280 end
281
282 indicate err false
283
284 if (Is_SuperFind_Required(self,iFile)) ;
285 send Request_SuperFind eFindMode iFile iField
286 else if bDeferred ;
287 send Request_Read eFindMode iFile iIndex
288 else ;
289 send Request_Find eFindMode iFile iIndex
290
291 If (not(found) and not(err)) begin
292 // refind original record (or leave it cleared if not record)
293 Move (FindByRowId(iFile,riRow)) to bOk
294
295 if bShowFindErr ;
296 error (if(eFindMode<2, DFERR_FIND_PRIOR_BEG_OF_FILE, DFERR_FIND_PAST_END_OF_FILE))
297 indicate FOUND FALSE
298 end
299 end
300 else ;
301 if bShowFindErr error DFERR_FIELD_NOT_INDEXED
302 end_procedure
303
304
305 // We only care about should_saves of DEOs and not DSOs when
306 // exiting the app. Create a handler for data set class. We still
307 // broadcast in case we've got nested deos in the dso (hopefully not).
308 //
309 { Visibility=Private }
310 Function Exit_Application_Check Returns Integer
311 Integer rVal
312 BroadCast Get Exit_Application_Check to Rval // check w/ kids
313 Function_return rVal
314 End_Function
315
316 { Visibility=Private }
317 Procedure Constrain
318 Integer iFile
319 Send OnConstrain
320 Forward Send Constrain
321 Get Constrain_File to iFile
322 If iFile ;
323 Constrain (Main_file(self)) relates to iFile
324 End_procedure
325
326 { MethodType=Event }
327 Procedure OnConstrain
328 End_Procedure
329
330 // Less confusing Message for adding Updating servers
331 //
332 { MethodType=Property }
333 { DesignTime=False }
334 Procedure Set DDO_Server Handle ObjId
335 Send Attach_Server ObjId
336 End_Procedure // Set DDO_Server
337
338 // This is called when a view takes or retakes the
339 // focus. If DD not in use, do nothing.
340 //
341 { Visibility=Private }
342 Procedure Refind_DD_Records
343 if (in_use_state(self)) Send refind_records
344 end_procedure
345
346 // this returns true if the data-set is changed AND there are attached
347 // DEO objects. Without this you can get "changes exist" condition reported
348 // that the user will have no way of saving.
349 //
350 { Visibility=Private MethodType=Property }
351 Function Data_Set_Should_Save returns integer
352 Function_Return (Should_Save(self) AND ;
353 Data_Set_User_interface_count(self))
354 End_Function
355
356 // returns 0 indicating that this is not DD enabled. DataDictionary objects will return 1.
357 // Add DSOs and DDOs must understand this message
358
359 { MethodType=Property Visibility=Private }
360 Function Extended_DSO_State Returns Integer
361 Function_return 0
362 End_Function // Extended_DSO_State
363
364
365end_class
366
367//#COMMAND bind_main_file // this should not be used anymore
368// #IF (!0>1)
369// #IFSAME !1 MAIN_FILE
370// #IFDEF !2.RECNUM
371// #PUSH !u
372// #SET U$ !2.RECNUM
373// set main_file to |CI!u
374// #POP u$
375// #ELSE
376// #ERROR DFERR_COMPILE If !2 is a file it is unopened
377// #ENDIF
378// #ELSE
379// bind_main_file !2 !3 !4 !5 !6 !7 !8 !9
380// #ENDIF
381// #ENDIF
382//#ENDCOMMAND
383
384//#COMMAND bind_index
385// #IF (!0>1)
386// #IFSAME !1 BY
387// set ordering to !2
388// #ELSE
389// bind_index !2 !3 !4 !5 !6 !7 !8 !9
390// #ENDIF
391// #ENDIF
392//#ENDCOMMAND
393
394//#COMMAND Bind_Updating
395// #IF (!0>1)
396// #IFSAME !1 UPDATING
397// SetDependents !2 !3 !4 !5 !6 !7 !8 !9
398// #ELSE
399// Bind_Updating !2 !3 !4 !5 !6 !7 !8 !9
400// #ENDIF
401// #ENDIF
402//#ENDCOMMAND
403
404//#COMMAND SetDependents //<File>|<Server#> [ ... ] ...obsolete
405// #IF (!0>0)
406// #IFDEF !1
407// send Attach_Server !1
408// #ELSE
409// #IFDEF !1.OBJ
410// send attach_Server !1.OBJ
411// #ELSE
412// #IFDEF !1.RECNUM
413// #PUSH !u
414// #SET U$ !1.RECNUM
415// send Add_Parent_File |CI!u
416// #POP U$
417// #ELSE
418// #ERROR DFERR_COMPILE If !1 is a file it is unopened
419// #ENDIF
420// #ENDIF
421// #ENDIF
422// SetDependents !2 !3 !4 !5 !6 !7 !8 !9
423// #ENDIF
424//#ENDCOMMAND
425
426#COMMAND BEGIN_CONSTRAINTS
427 procedure Constrain
428#ENDCOMMAND
429
430#COMMAND END_CONSTRAINTS
431 forward send constrain
432 end_procedure
433#ENDCOMMAND
434