481 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Rexx
		
	
	
	
	
	
		
		
			
		
	
	
			481 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Rexx
		
	
	
	
	
	
| 
								 | 
							
								/*----------------------------------------------------------------------------*/
							 | 
						||
| 
								 | 
							
								/*                                                                            */
							 | 
						||
| 
								 | 
							
								/* Copyright (c) 2011-2014 Rexx Language Association. All rights reserved.    */
							 | 
						||
| 
								 | 
							
								/*                                                                            */
							 | 
						||
| 
								 | 
							
								/* This program and the accompanying materials are made available under       */
							 | 
						||
| 
								 | 
							
								/* the terms of the Common Public License v1.0 which accompanies this         */
							 | 
						||
| 
								 | 
							
								/* distribution. A copy is also available at the following address:           */
							 | 
						||
| 
								 | 
							
								/* https://www.oorexx.org/license.html                                        */
							 | 
						||
| 
								 | 
							
								/*                                                                            */
							 | 
						||
| 
								 | 
							
								/* Redistribution and use in source and binary forms, with or                 */
							 | 
						||
| 
								 | 
							
								/* without modification, are permitted provided that the following            */
							 | 
						||
| 
								 | 
							
								/* conditions are met:                                                        */
							 | 
						||
| 
								 | 
							
								/*                                                                            */
							 | 
						||
| 
								 | 
							
								/* Redistributions of source code must retain the above copyright             */
							 | 
						||
| 
								 | 
							
								/* notice, this list of conditions and the following disclaimer.              */
							 | 
						||
| 
								 | 
							
								/* Redistributions in binary form must reproduce the above copyright          */
							 | 
						||
| 
								 | 
							
								/* notice, this list of conditions and the following disclaimer in            */
							 | 
						||
| 
								 | 
							
								/* the documentation and/or other materials provided with the distribution.   */
							 | 
						||
| 
								 | 
							
								/*                                                                            */
							 | 
						||
| 
								 | 
							
								/* Neither the name of Rexx Language Association nor the names                */
							 | 
						||
| 
								 | 
							
								/* of its contributors may be used to endorse or promote products             */
							 | 
						||
| 
								 | 
							
								/* derived from this software without specific prior written permission.      */
							 | 
						||
| 
								 | 
							
								/*                                                                            */
							 | 
						||
| 
								 | 
							
								/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS        */
							 | 
						||
| 
								 | 
							
								/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT          */
							 | 
						||
| 
								 | 
							
								/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS          */
							 | 
						||
| 
								 | 
							
								/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT   */
							 | 
						||
| 
								 | 
							
								/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,      */
							 | 
						||
| 
								 | 
							
								/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED   */
							 | 
						||
| 
								 | 
							
								/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,        */
							 | 
						||
| 
								 | 
							
								/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY     */
							 | 
						||
| 
								 | 
							
								/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING    */
							 | 
						||
| 
								 | 
							
								/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS         */
							 | 
						||
| 
								 | 
							
								/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.               */
							 | 
						||
| 
								 | 
							
								/*                                                                            */
							 | 
						||
| 
								 | 
							
								/*----------------------------------------------------------------------------*/
							 | 
						||
| 
								 | 
							
								/* ooDialog User Guide
							 | 
						||
| 
								 | 
							
								   Exercise 05: ProductView.rex - The ProductView component	  v01-00 03Jun12
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   Contains: 	   classes "ProductView" and "AboutDialog".
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   Pre-requisites: ProductView.dll, ProductView.h.
							 | 
						||
| 
								 | 
							
								   		   Support\NumberOnlyEditEx.cls (copied from ooDialog Samples)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   Description: A sample Product View component - part of the sample
							 | 
						||
| 
								 | 
							
								        	Order Management application.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   Changes:
							 | 
						||
| 
								 | 
							
								     v01-00 03Jun12: First version.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								------------------------------------------------------------------------------*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								::requires "ooDialog.cls"
							 | 
						||
| 
								 | 
							
								::requires "Support\NumberOnlyEditEx.cls"
							 | 
						||
| 
								 | 
							
								::requires "ProductModelData.rex"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								  ==============================================================================
							 | 
						||
| 
								 | 
							
								  ProductView							  v01-00 03Jun12
							 | 
						||
| 
								 | 
							
								  -----------
							 | 
						||
| 
								 | 
							
								  The "view" part of the Product business component.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  Changes:
							 | 
						||
| 
								 | 
							
								    v01-00 03Jun12: First version.
							 | 
						||
| 
								 | 
							
								  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								::CLASS ProductView SUBCLASS ResDialog PUBLIC
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ::ATTRIBUTE dialogState PRIVATE	-- States are: 'closable' or 'inUpdate".
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								    Class Methods:
							 | 
						||
| 
								 | 
							
								    --------------------------------------------------------------------------*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ::METHOD newInstance CLASS PUBLIC UNGUARDED
							 | 
						||
| 
								 | 
							
								    say ".ProductView-newInstance-01: Start."
							 | 
						||
| 
								 | 
							
								    -- Enable use of symbolic IDs in menu creation, and turn off AutoDetection
							 | 
						||
| 
								 | 
							
								    -- (the third parameter:
							 | 
						||
| 
								 | 
							
								    .Application~setDefaults("O", "ProductView.h", .false)
							 | 
						||
| 
								 | 
							
								    -- Create an instance of ProductView and show it:
							 | 
						||
| 
								 | 
							
								    dlg = .ProductView~new("res\ProductView.dll", IDD_PRODUCT_VIEW)
							 | 
						||
| 
								 | 
							
								    say ".ProductView-newInstance-02: dlg~Activate."
							 | 
						||
| 
								 | 
							
								    dlg~activate
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								    Instance Methods:
							 | 
						||
| 
								 | 
							
								    --------------------------------------------------------------------------*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								    Dialog Setup Methods:
							 | 
						||
| 
								 | 
							
								    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD init
							 | 
						||
| 
								 | 
							
								    say "ProductView-init-01."
							 | 
						||
| 
								 | 
							
								    -- called first (result of .ProductView~new)
							 | 
						||
| 
								 | 
							
								    forward class (super) continue
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD activate UNGUARDED
							 | 
						||
| 
								 | 
							
								    say "ProductView-activate-01."
							 | 
						||
| 
								 | 
							
								    self~dialogState = "closable"
							 | 
						||
| 
								 | 
							
								    self~execute("SHOWTOP","IDB_PROD_ICON")
							 | 
						||
| 
								 | 
							
								    return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD initDialog
							 | 
						||
| 
								 | 
							
								    expose menuBar prodControls prodData
							 | 
						||
| 
								 | 
							
								    say "ProductView-initDialog-01"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    menuBar = .BinaryMenuBar~new(self, IDR_PRODUCT_VIEW_MENU, , self, .true)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    prodControls = .Directory~new
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdNo]         = self~newEdit("IDC_PROD_NO")
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdName]       = self~newEdit("IDC_PROD_NAME")
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdPrice]      = self~newEdit("IDC_PROD_LIST_PRICE")
							 | 
						||
| 
								 | 
							
								    prodControls[ecUOM]            = self~newEdit("IDC_PROD_UOM")
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdDescr]      = self~newEdit("IDC_PROD_DESCRIPTION")
							 | 
						||
| 
								 | 
							
								    prodControls[gbSizes]          = self~newEdit("IDC_PROD_SIZE_GROUP")		-- Do we ever need this?
							 | 
						||
| 
								 | 
							
								    prodControls[rbSmall]          = self~newRadioButton("IDC_PROD_RADIO_SMALL")
							 | 
						||
| 
								 | 
							
								    prodControls[rbMedium]         = self~newRadioButton("IDC_PROD_RADIO_MEDIUM")
							 | 
						||
| 
								 | 
							
								    prodControls[rbLarge]          = self~newRadioButton("IDC_PROD_RADIO_LARGE")
							 | 
						||
| 
								 | 
							
								    prodControls[pbSaveChanges]    = self~newPushButton("IDC_PROD_SAVE_CHANGES")
							 | 
						||
| 
								 | 
							
								    self~connectButtonEvent("IDC_PROD_SAVE_CHANGES","CLICKED",saveChanges)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    -- Use NumberOnlyEditEx.cls to enforce numeric only entry for Price and UOM:
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdPrice]~initDecimalOnly(2,.false)		-- 2 decimal places, no sign.
							 | 
						||
| 
								 | 
							
								    prodControls[ecUOM]~initDecimalOnly(0,.false)		-- 0 decimal places, no sign.
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdPrice]~connectCharEvent(onChar)
							 | 
						||
| 
								 | 
							
								    prodControls[ecUOM]~connectCharEvent(onChar)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    prodData = self~getData	-- Gets data from ProductModel into prodData
							 | 
						||
| 
								 | 
							
								    self~showData	-- Show the data
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								    Event Handler Methods - MenuBar Events:
							 | 
						||
| 
								 | 
							
								    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD updateProduct UNGUARDED
							 | 
						||
| 
								 | 
							
								    expose prodControls
							 | 
						||
| 
								 | 
							
								say "ProductView-updateProduct-01."
							 | 
						||
| 
								 | 
							
								    -- Enable the controls to allow changes to the data:
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdName]~setReadOnly(.false)
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdPrice]~setReadOnly(.false)
							 | 
						||
| 
								 | 
							
								    prodControls[ecUOM]~setReadOnly(.false)
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdDescr]~setReadOnly(.false)
							 | 
						||
| 
								 | 
							
								    prodControls[rbSmall]~enable
							 | 
						||
| 
								 | 
							
								    prodControls[rbMedium]~enable
							 | 
						||
| 
								 | 
							
								    prodControls[rbLarge]~enable
							 | 
						||
| 
								 | 
							
								    self~enableControl("IDC_PROD_SAVE_CHANGES")
							 | 
						||
| 
								 | 
							
								    prodControls[pbSaveChanges]~state = "FOCUS"  -- Put input focus on the button
							 | 
						||
| 
								 | 
							
								    self~tabToNext()				 -- put text cursor on Product Description
							 | 
						||
| 
								 | 
							
								    						 --   (as if the user had pressed tab)
							 | 
						||
| 
								 | 
							
								    self~dialogState = "inUpdate"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD refreshData UNGUARDED
							 | 
						||
| 
								 | 
							
								    self~disableControl("IDC_PROD_SAVE_CHANGES")
							 | 
						||
| 
								 | 
							
								    self~showData
							 | 
						||
| 
								 | 
							
								    self~dialogState = "closable"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD print UNGUARDED
							 | 
						||
| 
								 | 
							
								    say "ProductView-print-01"
							 | 
						||
| 
								 | 
							
								    ret = InfoDialog(.HRS~printMsg)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD close UNGUARDED
							 | 
						||
| 
								 | 
							
								    say "ProductView-close-01"
							 | 
						||
| 
								 | 
							
								    self~cancel
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD about UNGUARDED
							 | 
						||
| 
								 | 
							
								    say "ProductView-about-01"
							 | 
						||
| 
								 | 
							
								    dlg = .AboutDialog~new("ProductView.dll", IDD_PRODUCT_VIEW_ABOUT)
							 | 
						||
| 
								 | 
							
								    dlg~execute("SHOWTOP")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								    Event Handler Methods - PushButton Events:
							 | 
						||
| 
								 | 
							
								    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
							 | 
						||
| 
								 | 
							
								    "Save Changes" - Collects new data, checks if there has indeed been a
							 | 
						||
| 
								 | 
							
								                     change, and if not, issues a warning msg. Disables the
							 | 
						||
| 
								 | 
							
								                     button when valid changes made.                          */
							 | 
						||
| 
								 | 
							
								  ::METHOD saveChanges UNGUARDED
							 | 
						||
| 
								 | 
							
								    expose prodControls prodData
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    -- Transform data from view format (as in controls) to app format (a directory):
							 | 
						||
| 
								 | 
							
								    newProdData = self~xformView2App(prodControls)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    -- Check if anything's changed; if not, show msgbox and exit with controls enabled.
							 | 
						||
| 
								 | 
							
								    -- If changed, go on to validate data.
							 | 
						||
| 
								 | 
							
								    result = self~checkForChanges(newProdData)
							 | 
						||
| 
								 | 
							
								    if result = .false then do
							 | 
						||
| 
								 | 
							
								      msg = .HRS~nilSaved
							 | 
						||
| 
								 | 
							
								      hwnd = self~dlgHandle
							 | 
						||
| 
								 | 
							
								      answer = MessageDialog(msg,hwnd,.HRS~updateProd,"OK","WARNING","DEFBUTTON2 APPLMODAL")
							 | 
						||
| 
								 | 
							
								      return
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    -- Now validate data:
							 | 
						||
| 
								 | 
							
								    result = self~validate(newProdData)		-- returns a null string or error messages.
							 | 
						||
| 
								 | 
							
								         					-- Better would be a set of error numbers.
							 | 
						||
| 
								 | 
							
								    -- If no problems, then show msgbox and go on to disable controls.
							 | 
						||
| 
								 | 
							
								    if result = "" then do
							 | 
						||
| 
								 | 
							
								      msg = .HRS~saved
							 | 
						||
| 
								 | 
							
								      hwnd = self~dlgHandle
							 | 
						||
| 
								 | 
							
								      answer = MessageDialog(msg,hwnd,.HRS~updateProd,"OK","INFORMATION","DEFBUTTON1 APPLMODAL")
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    -- If problems, then show msgbox and leave user to try again or refresh or exit.
							 | 
						||
| 
								 | 
							
								    else do
							 | 
						||
| 
								 | 
							
								      msg = result||.EndOfLine||.HRS~notSaved
							 | 
						||
| 
								 | 
							
								      hwnd = self~dlgHandle
							 | 
						||
| 
								 | 
							
								      answer = MessageDialog(msg,hwnd,.HRS~updateProd,"OK","ERROR","DEFBUTTON1 APPLMODAL")
							 | 
						||
| 
								 | 
							
								      return
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    -- Send new data to be checked by CustomerModel object (not implemented).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    -- Disable controls that were enabled by menu "ActionsFile-->Update" selection:
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdName]~setReadOnly(.true)
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdDescr]~setReadOnly(.true)
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdPrice]~setReadOnly(.true)
							 | 
						||
| 
								 | 
							
								    prodControls[ecUom]~setReadOnly(.true)
							 | 
						||
| 
								 | 
							
								    if newProdData~size \= "S" then prodControls[rbSmall]~disable
							 | 
						||
| 
								 | 
							
								    if newProdData~size \= "M" then prodControls[rbMedium]~disable
							 | 
						||
| 
								 | 
							
								    if newProdData~size \= "L" then prodControls[rbLarge]~disable
							 | 
						||
| 
								 | 
							
								    self~disableControl("IDC_PROD_SAVE_CHANGES")
							 | 
						||
| 
								 | 
							
								    self~dialogState = "closable"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    prodData = newProdData
							 | 
						||
| 
								 | 
							
								    prodData~list
							 | 
						||
| 
								 | 
							
								    return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								    Event Handler Methods - Keyboard Events:
							 | 
						||
| 
								 | 
							
								    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD onChar UNGUARDED
							 | 
						||
| 
								 | 
							
								    -- called for each character entered in the price or UOM fields.
							 | 
						||
| 
								 | 
							
								    forward to (arg(6))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD cancel
							 | 
						||
| 
								 | 
							
								    -- If in the process of updating, then ask whether any changes should be
							 | 
						||
| 
								 | 
							
								    -- thrown away and dialog closed. If yes then close by calling the superclass,
							 | 
						||
| 
								 | 
							
								    -- else nop. If not in update, then close immediately
							 | 
						||
| 
								 | 
							
								    say "ProductView-cancel-01."
							 | 
						||
| 
								 | 
							
								    if self~dialogState = "inUpdate" then do
							 | 
						||
| 
								 | 
							
								      ans = MessageDialog(.HRS~closeInUpdate, self~dlgHandle, .HRS~updateIP, "YESNO", "WARNING", "DEFBUTTON2")
							 | 
						||
| 
								 | 
							
								      if ans = .PlainBaseDialog~IDYES then return self~cancel:super
							 | 
						||
| 
								 | 
							
								      else nop
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    else return self~cancel:super
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								    Application Methods:
							 | 
						||
| 
								 | 
							
								    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD getData
							 | 
						||
| 
								 | 
							
								    -- Get data from the ProductModel:
							 | 
						||
| 
								 | 
							
								    --expose prodData
							 | 
						||
| 
								 | 
							
								    say "ProductView-getData-01."
							 | 
						||
| 
								 | 
							
								    idProductModel = .local~my.idProductModel
							 | 
						||
| 
								 | 
							
								    prodData = idProductModel~query		-- prodData is of type ProductDT
							 | 
						||
| 
								 | 
							
								    return prodData
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD showData
							 | 
						||
| 
								 | 
							
								    -- Transfrom data (where necessary) to display format, and then disable controls.
							 | 
						||
| 
								 | 
							
								    expose prodControls prodData
							 | 
						||
| 
								 | 
							
								    say "ProductView-showData-01."
							 | 
						||
| 
								 | 
							
								    -- Set data in controls:
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdNo]~setText(   prodData~number       )
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdName]~setText( prodData~name         )
							 | 
						||
| 
								 | 
							
								    -- Price in prodData has no decimal point - 2 decimal places are implied - hence /100 for display.
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdPrice]~setText(prodData~price/100    )
							 | 
						||
| 
								 | 
							
								    prodControls[ecUOM]~settext(      proddata~uom          )
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdDescr]~setText(prodData~description  )
							 | 
						||
| 
								 | 
							
								    size = prodData~size
							 | 
						||
| 
								 | 
							
								    -- Disable controls
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdName]~setReadOnly(.true)
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdPrice]~setReadOnly(.true)
							 | 
						||
| 
								 | 
							
								    prodControls[ecUOM]~setReadOnly(.true)
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdDescr]~setReadOnly(.true)
							 | 
						||
| 
								 | 
							
								    prodControls[rbSmall]~disable
							 | 
						||
| 
								 | 
							
								    prodControls[rbMedium]~disable
							 | 
						||
| 
								 | 
							
								    prodControls[rbLarge]~disable
							 | 
						||
| 
								 | 
							
								    -- But check correct button and enable it to highlight it to the user:
							 | 
						||
| 
								 | 
							
								    select
							 | 
						||
| 
								 | 
							
								      when size = "S" then do
							 | 
						||
| 
								 | 
							
								        .RadioButton~checkInGroup(self,"IDC_PROD_RADIO_SMALL","IDC_PROD_RADIO_LARGE","IDC_PROD_RADIO_SMALL")
							 | 
						||
| 
								 | 
							
								        prodcontrols[rbSmall]~enable
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								      when size = "M" then do
							 | 
						||
| 
								 | 
							
								        .RadioButton~checkInGroup(self,"IDC_PROD_RADIO_SMALL","IDC_PROD_RADIO_LARGE","IDC_PROD_RADIO_MEDIUM")
							 | 
						||
| 
								 | 
							
								        prodcontrols[rbMedium]~enable
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								      otherwise do
							 | 
						||
| 
								 | 
							
								        .RadioButton~checkInGroup(self,"IDC_PROD_RADIO_SMALL","IDC_PROD_RADIO_LARGE","IDC_PROD_RADIO_LARGE")
							 | 
						||
| 
								 | 
							
								        prodcontrols[rbLarge]~enable
							 | 
						||
| 
								 | 
							
								      end
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD checkForChanges
							 | 
						||
| 
								 | 
							
								    -- Check whether any data has actually changed when "Save Changes" button
							 | 
						||
| 
								 | 
							
								    -- has been pressed. Return .true if data changed, else returns .false.
							 | 
						||
| 
								 | 
							
								    expose prodData
							 | 
						||
| 
								 | 
							
								    use arg newProdData
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    changed = .false
							 | 
						||
| 
								 | 
							
								    select
							 | 
						||
| 
								 | 
							
								      when newProdData~name        \= prodData~name        then changed = .true
							 | 
						||
| 
								 | 
							
								      when newProdData~price       \= prodData~price       then changed = .true
							 | 
						||
| 
								 | 
							
								      when newProdData~uom         \= prodData~uom         then changed = .true
							 | 
						||
| 
								 | 
							
								      when newProdData~description \= prodData~description then changed = .true
							 | 
						||
| 
								 | 
							
								      when newProdData~size        \= ProdData~size        then changed = .true
							 | 
						||
| 
								 | 
							
								      otherwise nop
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    return changed
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD validate
							 | 
						||
| 
								 | 
							
								    -- Validation: 1. Check price/UOM not changed > 50% up or down.
							 | 
						||
| 
								 | 
							
								    --             2. Cannot change from Large to Small without UOM increasing
							 | 
						||
| 
								 | 
							
								    --                 by at least 100%; nor from Small to Large without
							 | 
						||
| 
								 | 
							
								    --                 decreasing by more than 50%.
							 | 
						||
| 
								 | 
							
								    --             3. Product Description <= 100 characters.
							 | 
						||
| 
								 | 
							
								    --             4. Product Name <= 30 characters.
							 | 
						||
| 
								 | 
							
								    --  Returns string of messages - the null string if all OK.
							 | 
						||
| 
								 | 
							
								    expose prodData
							 | 
						||
| 
								 | 
							
								    use arg newProdData
							 | 
						||
| 
								 | 
							
								    msg = ""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    -- Check Price (catches decimal point errors also):
							 | 
						||
| 
								 | 
							
								    price = prodData~price; newPrice = newProdData~price
							 | 
						||
| 
								 | 
							
								    oldUom   = prodData~uom;       newUom   = newProdData~uom 	-- 'oldUom - avoids name conflict with 'uom' in newProddata~uom.
							 | 
						||
| 
								 | 
							
								    if ((price/oldUom)*1.5 < newPrice/newUom) | (newPrice/newUom < (price/oldUom)/2) then do
							 | 
						||
| 
								 | 
							
								      msg = msg||.HRS~badRatio||" "
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    -- Check Size vs UOM:
							 | 
						||
| 
								 | 
							
								    if prodData~size = "L" & newProdData~size = "S" -    -- Large to Small
							 | 
						||
| 
								 | 
							
								        & prodData~uom/2 < newProdData~uom then do
							 | 
						||
| 
								 | 
							
								      msg = msg||.HRS~uomTooBig||" "
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								      if prodData~size = "S" & newProdData~size = "L" -    -- Small to Large
							 | 
						||
| 
								 | 
							
								        & prodData~uom*2 > newProdData~uom then do
							 | 
						||
| 
								 | 
							
								      msg = msg||.HRS~uomTooSmall||" "
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    -- Check Product Description length:
							 | 
						||
| 
								 | 
							
								    if newProdData.description~length > 80 then do
							 | 
						||
| 
								 | 
							
								      msg = msg||.HRS~descrTooBig||" "
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    -- Check Product Name length:
							 | 
						||
| 
								 | 
							
								    if newProdData~name~length > 30 then do
							 | 
						||
| 
								 | 
							
								      msg = msg||.HRS~prodNameTooBig
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return msg
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::METHOD xformView2App
							 | 
						||
| 
								 | 
							
								    -- Transforms Product Data from View form (in the GUI controls) to
							 | 
						||
| 
								 | 
							
								    --   App form (a directory with address as an array).
							 | 
						||
| 
								 | 
							
								    expose prodControls
							 | 
						||
| 
								 | 
							
								    prodData = .ProductDT~new
							 | 
						||
| 
								 | 
							
								    prodData~number = prodControls[ecProdNo]~gettext()
							 | 
						||
| 
								 | 
							
								    prodData~name = prodControls[ecProdName]~getText()
							 | 
						||
| 
								 | 
							
								    price = prodControls[ecProdPrice]~getText()
							 | 
						||
| 
								 | 
							
								    -- Data entered has or assumes a decimal point; but data in "application"
							 | 
						||
| 
								 | 
							
								    --   is a whole number (e.g. $42.42 is recorded in the database as "4242").
							 | 
						||
| 
								 | 
							
								    --   So re-format data from decimal to whole number:
							 | 
						||
| 
								 | 
							
								    priceTwoDecs = price~format(,2)		-- force 2 dec positions
							 | 
						||
| 
								 | 
							
								    -- Re-display price properly formatted (in case the user did not format correctly - e.g. entered "42" or "38.4"):
							 | 
						||
| 
								 | 
							
								    prodControls[ecProdPrice]~setText(priceTwoDecs)
							 | 
						||
| 
								 | 
							
								    -- Now format price to "application" format:
							 | 
						||
| 
								 | 
							
								    price = (priceTwoDecs*100)~format(,0)	-- multiply by 100 and then force whole number.
							 | 
						||
| 
								 | 
							
								    prodData~price = price
							 | 
						||
| 
								 | 
							
								    prodData~uom  = prodControls[ecUOM]~getText()
							 | 
						||
| 
								 | 
							
								    prodData~description = prodControls[ecProdDescr]~getText()
							 | 
						||
| 
								 | 
							
								    select
							 | 
						||
| 
								 | 
							
								      when prodControls[rbSmall]~checked then prodData~size = "S"
							 | 
						||
| 
								 | 
							
								      when prodControls[rbMedium]~checked then prodData~size = "M"
							 | 
						||
| 
								 | 
							
								      otherwise prodData~size = "L"
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return prodData
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*============================================================================*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								  ==============================================================================
							 | 
						||
| 
								 | 
							
								  AboutDialog							  v01-00 03Jun12
							 | 
						||
| 
								 | 
							
								  -------------
							 | 
						||
| 
								 | 
							
								  The "About" class - shows a dialog box that includes a bitmap - part of the
							 | 
						||
| 
								 | 
							
								  ProductView component.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  Changes:
							 | 
						||
| 
								 | 
							
								    v01-00 03Jun12: First version.
							 | 
						||
| 
								 | 
							
								  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								::CLASS AboutDialog SUBCLASS ResDialog
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::method initDialog
							 | 
						||
| 
								 | 
							
								    expose font image
							 | 
						||
| 
								 | 
							
								    resImage = .ResourceImage~new(self)			  -- Create an instance of a resource image
							 | 
						||
| 
								 | 
							
								    image = resImage~getImage(IDB_PROD_ICON)			  -- Create an image from the Product bitmap
							 | 
						||
| 
								 | 
							
								    stImage = self~newStatic(IDC_PRODABT_ICON_PLACE)~setImage(image) -- Create a static text control and set the image in it
							 | 
						||
| 
								 | 
							
								    font = self~createFontEx("Ariel", 12)			  -- Create up a largish font with which to display text and ...
							 | 
						||
| 
								 | 
							
								    self~newStatic(IDC_PRODABT_STATIC2)~setFont(font)		  -- ... set the static text to use that font.
							 | 
						||
| 
								 | 
							
								    -- Provide for a double-click in Product icon:
							 | 
						||
| 
								 | 
							
								    self~connectStaticNotify("IDC_PRODABT_ICON_PLACE", "DBLCLK", showMsgBox)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::method showMsgBox
							 | 
						||
| 
								 | 
							
								    say "AboutDialog-showMsgBox-01."
							 | 
						||
| 
								 | 
							
								    ans = MessageDialog(.HRS~aboutDblClick)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								  ::method leaving
							 | 
						||
| 
								 | 
							
								    expose font image
							 | 
						||
| 
								 | 
							
								    self~deleteFont(font)
							 | 
						||
| 
								 | 
							
								    image~release()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*============================================================================*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								  ==============================================================================
							 | 
						||
| 
								 | 
							
								  Human-Readable Strings (HRS)					  v01-00 03Jun12
							 | 
						||
| 
								 | 
							
								  --------
							 | 
						||
| 
								 | 
							
								   The HRS class provides constant character strings for user-visible messages.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   Changes:
							 | 
						||
| 
								 | 
							
								     v01-00 03Jun12: First version.
							 | 
						||
| 
								 | 
							
								  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								::CLASS HRS PRIVATE		-- Human-Readable Strings
							 | 
						||
| 
								 | 
							
								  ::CONSTANT aboutDblClick  "You double-clicked!"
							 | 
						||
| 
								 | 
							
								  ::CONSTANT badRatio	    "The new price/UOM ratio cannot be changed more than 50% up or down."
							 | 
						||
| 
								 | 
							
								  ::CONSTANT closeInUpdate  "Any changes made will be lost. Exit anyway?"
							 | 
						||
| 
								 | 
							
								  ::CONSTANT descrTooBig    "The Product Description is too long."
							 | 
						||
| 
								 | 
							
								  ::CONSTANT nilSaved       "Nothing was changed! Data not saved."
							 | 
						||
| 
								 | 
							
								  ::CONSTANT notSaved       "Changes Not Saved!"
							 | 
						||
| 
								 | 
							
								  ::CONSTANT prodNameTooBig "The Product Name is too long."
							 | 
						||
| 
								 | 
							
								  ::CONSTANT saved	    "Changes saved."
							 | 
						||
| 
								 | 
							
								  ::CONSTANT uomTooBig      "The new UOM is too large."
							 | 
						||
| 
								 | 
							
								  ::CONSTANT uomTooSmall    "The new UOM is too small."
							 | 
						||
| 
								 | 
							
								  ::CONSTANT updateIP       "Update in process"
							 | 
						||
| 
								 | 
							
								  ::CONSTANT updateProd     "Update Product"
							 | 
						||
| 
								 | 
							
								  ::CONSTANT printMsg       "The 'Print...' menu item is not yet implemented."
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*============================================================================*/
							 |