1059 lines
29 KiB
Rexx
Executable File
1059 lines
29 KiB
Rexx
Executable File
/*----------------------------------------------------------------------------*/
|
|
/* */
|
|
/* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
|
|
/* Copyright (c) 2005-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. */
|
|
/* */
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Name: employee11tab.rex
|
|
* Type: Open Object REXX Script
|
|
*
|
|
* Description: Example to demonstrate the property sheet dialog class.
|
|
*/
|
|
|
|
sd = locate()
|
|
|
|
-- Note to self, we do not use data attributes in this app, need explanation.
|
|
.application~setDefaults("O", sd"employee11tab.h", .false)
|
|
|
|
-- Create the dialog pages.
|
|
p1 = .EmployeeAdd~new(sd"employee11tab.rc", IDD_EMPLOYEES_ADD)
|
|
p2 = .EmployeeEdit~new(sd"employee11tab.rc", IDD_EMPLOYEES_EDIT)
|
|
p3 = .EmployeeBrowse~new(sd"employee11tab.rc", IDD_EMPLOYEES_BROWSE)
|
|
p4 = .EmployeeList~new(sd"employee11tab.rc", IDD_EMPLOYEES_LIST)
|
|
|
|
pages = .array~of(p1, p2, p3, p4)
|
|
dlg = .AcmeEmployeesDlg~new(pages, "NOAPPLYNOW", "Acme Software - Employee Manager Version 10.00.0")
|
|
|
|
dlg~execute
|
|
|
|
return 0
|
|
|
|
::requires "ooDialog.cls"
|
|
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*\
|
|
AcmeEmployeesDlg - The property sheet dialog for this application.
|
|
\* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
|
::class 'AcmeEmployeesDlg' subclass PropertySheetDialog
|
|
|
|
::constant DATABASE 'employee11tab.db'
|
|
|
|
::attribute employees
|
|
::attribute empCount
|
|
::attribute empIndex
|
|
|
|
::method init
|
|
expose dbChanged
|
|
|
|
forward class (super) continue
|
|
|
|
self~readDataBase
|
|
|
|
dbChanged = .false
|
|
|
|
if self~employees~items == 0 then self~startPage = 1
|
|
else self~startPage = 4
|
|
|
|
do page over self~pages
|
|
page~configure(self~employees, self~empCount, self~empIndex)
|
|
end
|
|
|
|
|
|
::method newEmployeeNotify
|
|
expose dbChanged
|
|
use strict arg emp
|
|
|
|
dbChanged = .true
|
|
|
|
self~empCount += 1
|
|
self~employees[self~empCount] = emp
|
|
self~empIndex = self~empCount
|
|
|
|
self~notifyPages
|
|
|
|
listPage = self~pages[4]
|
|
|
|
-- If the user has not yet visited the List Employees page, then there is
|
|
-- no list view to update. Instead, when the user first visits that page,
|
|
-- the list view will be filled with all existing employees.
|
|
if listPage~wasActivated then listPage~newEmployeeNotify
|
|
|
|
|
|
::method editedEmployeeNotify
|
|
expose dbChanged
|
|
use strict arg emp
|
|
|
|
dbChanged = .true
|
|
self~employees[self~empIndex] = emp
|
|
|
|
listPage = self~pages[4]
|
|
if listPage~wasActivated then listPage~editedEmployeeNotify
|
|
|
|
self~setCurSel( , 4)
|
|
|
|
|
|
::method selectedEmployeeNotify
|
|
use strict arg index
|
|
|
|
self~empIndex = index
|
|
self~notifyPages
|
|
|
|
|
|
::method maybeDeleteEmployee
|
|
expose dbChanged
|
|
|
|
emp = self~employees[self~empIndex]
|
|
|
|
pronoun = 'him'
|
|
if \ emp~male then pronoun = 'her'
|
|
|
|
title = "Acme Software - Deleting Employee:" emp~name
|
|
msg = "Deleting" emp~name "will permanently remove" pronoun "from" || .endOfLine || -
|
|
'the database. No further pay checks can be issued to' emp~name'.' || .endOfLine~copies(2) || -
|
|
"Are you sure you want to continue this action?"
|
|
|
|
answer = MessageDialog(msg, self~hwnd, title, 'YESNO', 'QUESTION', 'DEFBUTTON2')
|
|
if answer == self~IDYES then do
|
|
oldIndex = self~empIndex
|
|
|
|
self~employees~delete(self~empIndex)
|
|
self~empCount -= 1
|
|
self~empIndex = 1
|
|
|
|
listPage = self~pages[4]
|
|
if listPage~wasActivated then listPage~deleteEmployeeNotify(oldIndex)
|
|
|
|
self~notifyPages
|
|
dbChanged = .true
|
|
end
|
|
|
|
::method leaving
|
|
expose dbChanged
|
|
|
|
if dbChanged & self~getResult == 'CLOSEDOK' then do
|
|
self~writeDataBase
|
|
end
|
|
|
|
|
|
::method notifyPages private
|
|
|
|
do page over self~pages
|
|
page~empCount = self~empCount
|
|
page~empIndex = self~empIndex
|
|
end
|
|
|
|
|
|
::method readDataBase private
|
|
|
|
db = self~DATABASE
|
|
|
|
fsObj = .stream~new(db)
|
|
if fsObj~query('EXISTS') == '' then do
|
|
self~employees = .array~new(10)
|
|
self~empCount = 0
|
|
self~empIndex = 0
|
|
end
|
|
else do
|
|
lines = fsObj~makeArray
|
|
fsObj~close
|
|
|
|
emps = .array~new(lines~items)
|
|
do l over lines
|
|
l = l~strip
|
|
if l~length == 0 | l~abbrev("#") | l~abbrev("/*") then iterate
|
|
|
|
parse var l name', 'city', 'pos', 'male', 'married', 'fullTime .
|
|
|
|
if male == 'M' then male = .true
|
|
else male = .false
|
|
|
|
if married == 'M' then married = .true
|
|
else married = .false
|
|
|
|
if fullTime == 'F' then fullTime = .true
|
|
else fullTime = .false
|
|
|
|
emp = .Employee~new(name, city, pos, male, married, fullTime)
|
|
emps~append(emp)
|
|
end
|
|
|
|
self~employees = emps
|
|
self~empCount = emps~items
|
|
self~empIndex = 1
|
|
end
|
|
|
|
|
|
::method writeDataBase private
|
|
|
|
db = self~DATABASE
|
|
|
|
fsObj = .stream~new(db)
|
|
|
|
fsObj~open('WRITE REPLACE')
|
|
|
|
if fsObj~state == 'READY' then do e over self~employees
|
|
line = e~toCSV
|
|
fsObj~lineout(line)
|
|
end
|
|
else do
|
|
title = "Acme Software - Internal Error Detected"
|
|
msg = "The database could not be opened to record current changes."
|
|
j = MessageDialog(msg, 0, title, 'OK', 'ERROR')
|
|
end
|
|
|
|
fsObj~close
|
|
|
|
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*\
|
|
EmployeeAdd - A dialog class for a page in the PropertySheetDialog. This page
|
|
allows the user to add employee records.
|
|
\* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
|
::class 'EmployeeAdd' subclass RcPSPDialog
|
|
|
|
::attribute employees
|
|
::attribute empCount
|
|
::attribute empIndex
|
|
::attribute empView
|
|
::attribute empInitial
|
|
|
|
::method configure
|
|
expose isChanged
|
|
use arg employees, count, index
|
|
|
|
self~employees = employess
|
|
self~empCount = count
|
|
self~empIndex = index
|
|
self~empInitial = .Employee~new()
|
|
|
|
self~connectEditEvent(IDC_EDIT_NAME_A, "CHANGE", onChange)
|
|
self~connectComboBoxEvent(IDC_CB_CITY_A, "SELCHANGE", onChange)
|
|
self~connectListBoxEvent(IDC_LB_POSITION_A, "SELCHANGE", onChange)
|
|
self~connectButtonEvent(IDC_RB_MALE_A, "CLICKED", onChange)
|
|
self~connectButtonEvent(IDC_RB_FEMALE_A, "CLICKED", onChange)
|
|
self~connectButtonEvent(IDC_CHK_MARRIED_A, "CLICKED", onChange)
|
|
self~connectButtonEvent(IDC_CHK_FULLTIME_A, "CLICKED", onChange)
|
|
isChanged = .false
|
|
|
|
self~connectButtonEvent(IDC_PB_PRINT_A, "CLICKED", onPrint)
|
|
self~connectButtonEvent(IDC_PB_ADD_A, "CLICKED", onAdd)
|
|
|
|
::method initDialog
|
|
expose cbCity lbPosition editName
|
|
|
|
self~setControls
|
|
self~empView~fillBoxes
|
|
|
|
editName~connectCharEvent(onChar)
|
|
|
|
-- If we are the start page, it means there are no employees. So we put up
|
|
-- a message box informing the user she needs to add employees through this
|
|
-- page.
|
|
if self~propSheet~startPage == 1 then do
|
|
title = "Acme Software - Employee Manager"
|
|
msg = "The Employee Database is empty." || .endOfLine~copies(2) || -
|
|
"Use the 'Add Employees' page to add employees."
|
|
|
|
ret = MessageDialog(msg, self~hwnd, title)
|
|
end
|
|
|
|
|
|
::method setActive unguarded
|
|
|
|
self~defaultForm
|
|
return 0
|
|
|
|
::method killActive unguarded
|
|
expose isChanged
|
|
use arg psDlg
|
|
|
|
if isChanged then do
|
|
title = "Acme Software - Add Employee"
|
|
msg = 'The addition of the new employee is not' || .endOfLine || -
|
|
'complete. Leaving this page will result' || .endOfLine || -
|
|
'in all changes being lost.' || .endOfLine~copies(2) || -
|
|
'To leave this page and abandon changes,' || .endOfLine || -
|
|
'press Ok. To stay on the page and con-' || .endOfLine || -
|
|
'tinue adding a new employee, press Cancel'
|
|
|
|
ret = MessageDialog(msg, self~hwnd, title, "OKCANCEL", "WARNING", 'DEFBUTTON2')
|
|
if ret == self~IDCANCEL then return .false
|
|
end
|
|
|
|
return .true
|
|
|
|
|
|
::method onPrint unguarded
|
|
|
|
currentEmployee = self~empView~createEmployee
|
|
currentEmployee~print(self)
|
|
return 0
|
|
|
|
|
|
::method onAdd unguarded
|
|
|
|
newEmployee = self~empView~createEmployee
|
|
self~propSheet~newEmployeeNotify(newEmployee)
|
|
|
|
self~defaultForm
|
|
return 0
|
|
|
|
|
|
::method onChar unguarded
|
|
use arg char, isShift, isCtrl, isAlt, misc, editControl
|
|
|
|
if char~d2c == ',' then do
|
|
result = ' '~c2d
|
|
reply result
|
|
|
|
msg = 'Employee names can not contain a comma. You can not type a comma here'
|
|
title = "Unacceptable Character"
|
|
editControl~showBalloon(title, msg, "ERROR")
|
|
end
|
|
else do
|
|
return .true
|
|
end
|
|
|
|
|
|
::method onChange unguarded
|
|
expose isChanged pbPrint pbAdd editName
|
|
|
|
if isChanged then do
|
|
if self~empView~sameAs(self~empInitial) then isChanged = .false
|
|
end
|
|
else do
|
|
if \ self~empView~sameAs(self~empInitial) then isChanged = .true
|
|
end
|
|
|
|
-- The Add and Print buttons are only enabled when there is some change and
|
|
-- the employee name is not blank. The status of the buttons *could* change
|
|
-- on any change, but only *will* change under certain cicrcumstances.
|
|
-- Rather than try to track and determine those exact circumstances, we just
|
|
-- check if the buttons should be enabled or not and do that on each change.
|
|
if isChanged, editName~getText~strip \== '' then do
|
|
pbPrint~enable
|
|
pbAdd~enable
|
|
end
|
|
else do
|
|
pbPrint~disable
|
|
pbAdd~disable
|
|
end
|
|
|
|
return 0
|
|
|
|
|
|
::method setControls private
|
|
expose editName cbCity lbPosition rbMale rbFemale chkMarried chkFullTime pbPrint pbAdd
|
|
|
|
editName = self~newEdit(IDC_EDIT_NAME_A)
|
|
cbCity = self~newComboBox(IDC_CB_CITY_A)
|
|
lbPosition = self~newListBox(IDC_LB_POSITION_A)
|
|
rbMale = self~newRadioButton(IDC_RB_MALE_A)
|
|
rbFemale = self~newRadioButton(IDC_RB_FEMALE_A)
|
|
chkMarried = self~newCheckBox(IDC_CHK_MARRIED_A)
|
|
chkFullTime = self~newCheckBox(IDC_CHK_FULLTIME_A)
|
|
|
|
self~empView = .EmployeeView~new(editName, cbCity, lbPosition, rbMale, rbFemale, chkMarried, chkFullTime)
|
|
|
|
pbPrint = self~newPushButton(IDC_PB_PRINT_A)
|
|
pbAdd = self~newPushButton(IDC_PB_ADD_A)
|
|
|
|
|
|
::method defaultForm private
|
|
expose pbPrint pbAdd
|
|
|
|
pbPrint~disable
|
|
pbAdd~disable
|
|
|
|
self~empView~displayEmployee(self~empInitial)
|
|
self~empView~editName~assignFocus
|
|
|
|
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*\
|
|
EmployeeEdit - A dialog class for a page in the PropertySheetDialog. This
|
|
page allows the user to edit an existing employee's record
|
|
\* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
|
::class 'EmployeeEdit' subclass RcPSPDialog
|
|
|
|
::attribute employees
|
|
::attribute empCount
|
|
::attribute empIndex
|
|
::attribute empInitial
|
|
::attribute empView
|
|
|
|
::method configure
|
|
expose isChanged
|
|
use arg employees, count, index
|
|
|
|
self~employees = employees
|
|
self~empCount = count
|
|
self~empIndex = index
|
|
|
|
self~empInitial = .nil
|
|
|
|
self~connectEditEvent(IDC_EDIT_NAME_E, "CHANGE", onChange)
|
|
self~connectComboBoxEvent(IDC_CB_CITY_E, "SELCHANGE", onChange)
|
|
self~connectListBoxEvent(IDC_LB_POSITION_E, "SELCHANGE", onChange)
|
|
self~connectButtonEvent(IDC_RB_MALE_E, "CLICKED", onChange)
|
|
self~connectButtonEvent(IDC_RB_FEMALE_E, "CLICKED", onChange)
|
|
self~connectButtonEvent(IDC_CHK_MARRIED_E, "CLICKED", onChange)
|
|
self~connectButtonEvent(IDC_CHK_FULLTIME_E, "CLICKED", onChange)
|
|
isChanged = .false
|
|
|
|
self~connectButtonEvent(IDC_PB_PRINT_E, "CLICKED", onPrint)
|
|
self~connectButtonEvent(IDC_PB_SAVE_E, "CLICKED", onSave)
|
|
self~connectButtonEvent(IDC_PB_RESET_E, "CLICKED", onReset)
|
|
|
|
|
|
::method initDialog
|
|
expose cbCity lbPosition
|
|
|
|
self~setControls
|
|
self~empView~fillBoxes
|
|
|
|
|
|
::method setActive unguarded
|
|
|
|
self~setEmpRecord
|
|
return 0
|
|
|
|
|
|
::method onPrint unguarded
|
|
|
|
if self~empInitial \== .nil then do
|
|
currentEmployee = self~empView~createEmployee
|
|
currentEmployee~print(self)
|
|
end
|
|
return 0
|
|
|
|
::method onSave unguarded
|
|
|
|
editedEmployee = self~empView~createEmployee
|
|
self~propSheet~editedEmployeeNotify(editedEmployee)
|
|
|
|
return 0
|
|
|
|
|
|
::method onReset unguarded
|
|
self~setEmpRecord
|
|
|
|
|
|
::method onChange unguarded
|
|
expose isChanged pbPrint pbSave pbReset editName
|
|
|
|
if self~empInitial == .nil then return 0
|
|
|
|
if isChanged then do
|
|
if self~empView~sameAs(self~empInitial) then isChanged = .false
|
|
end
|
|
else do
|
|
if \ self~empView~sameAs(self~empInitial) then isChanged = .true
|
|
end
|
|
|
|
txt = editName~getText~strip
|
|
|
|
if txt == '' then do
|
|
pbPrint~disable
|
|
pbSave~disable
|
|
pbReset~enable
|
|
end
|
|
else if isChanged then do
|
|
pbPrint~enable
|
|
pbSave~enable
|
|
pbReset~enable
|
|
end
|
|
else do
|
|
pbPrint~enable
|
|
pbSave~disable
|
|
pbReset~disable
|
|
end
|
|
|
|
return 0
|
|
|
|
|
|
::method setControls private
|
|
expose cbCity lbPosition rbMale rbFemale chkMarried chkFullTime editName pbPrint pbSave pbReset
|
|
|
|
cbCity = self~newComboBox(IDC_CB_CITY_E)
|
|
lbPosition = self~newListBox(IDC_LB_POSITION_E)
|
|
rbMale = self~newRadioButton(IDC_RB_MALE_E)
|
|
rbFemale = self~newRadioButton(IDC_RB_FEMALE_E)
|
|
chkMarried = self~newCheckBox(IDC_CHK_MARRIED_E)
|
|
chkFullTime = self~newCheckBox(IDC_CHK_FULLTIME_E)
|
|
editName = self~newEdit(IDC_EDIT_NAME_E)
|
|
|
|
self~empView = .EmployeeView~new(editName, cbCity, lbPosition, rbMale, rbFemale, chkMarried, chkFullTime)
|
|
|
|
pbReset = self~newPushButton(IDC_PB_RESET_E)
|
|
pbSave = self~newPushButton(IDC_PB_SAVE_E)
|
|
pbPrint = self~newPushButton(IDC_PB_PRINT_E)
|
|
|
|
|
|
::method setEmpRecord
|
|
expose pbSave pbPrint pbReset isChanged
|
|
|
|
if self~empCount < 1 then do
|
|
self~empView~disable
|
|
pbSave~disable
|
|
pbPrint~disable
|
|
pbReset~disable
|
|
return 0
|
|
end
|
|
|
|
isChanged = .false
|
|
pbSave~disable
|
|
pbPrint~enable
|
|
|
|
self~empInitial = self~employees[self~empIndex]
|
|
self~empView~displayEmployee(self~empInitial)
|
|
self~empView~editName~assignFocus
|
|
|
|
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*\
|
|
EmployeeBrowse - A dialog class for a page in the PropertySheetDialog. This
|
|
page allows the user to scroll through employee records one
|
|
at a time.
|
|
\* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
|
::class 'EmployeeBrowse' subclass RcPSPDialog
|
|
|
|
::attribute employees
|
|
::attribute empCount
|
|
::attribute empIndex
|
|
::attribute empView
|
|
|
|
::method configure
|
|
use arg employees, count, empIndex
|
|
|
|
self~employees = employees
|
|
self~empCount = count
|
|
self~empIndex = empIndex
|
|
|
|
self~connectButtonEvent(IDC_PB_PRINT_B, "CLICKED", onPrint)
|
|
self~connectUpDownEvent(IDC_UPD, "DELTAPOS", onEmpChange)
|
|
|
|
|
|
::method initDialog
|
|
expose upDown
|
|
|
|
self~setControls
|
|
self~empView~fillBoxes
|
|
|
|
|
|
::method setActive unguarded
|
|
|
|
self~updateUpdown
|
|
return 0
|
|
|
|
|
|
::method onPrint unguarded
|
|
|
|
if self~empCount > 0 then do
|
|
currentEmployee = self~empView~createEmployee
|
|
currentEmployee~print(self)
|
|
end
|
|
return 0
|
|
|
|
|
|
::method onEmpChange unguarded
|
|
use arg curPos, increment
|
|
|
|
self~setEmpRecord(curPos + increment)
|
|
return .UpDown~deltaPosReply
|
|
|
|
|
|
::method setEmpRecord private
|
|
expose upDown
|
|
use strict arg empIndex
|
|
|
|
if empIndex < 1 then return self~noRecord('bottom')
|
|
else if empIndex > upDown~getRange~max then return self~noRecord('top')
|
|
|
|
emp = self~employees[empIndex]
|
|
self~empView~displayEmployee(emp)
|
|
|
|
self~propSheet~selectedEmployeeNotify(empIndex)
|
|
|
|
|
|
::method setControls private
|
|
expose cbCity lbPosition rbMale rbFemale chkMarried chkFullTime editName upDown pbPrint
|
|
|
|
cbCity = self~newComboBox(IDC_CB_CITY_B)
|
|
lbPosition = self~newListBox(IDC_LB_POSITION_B)
|
|
rbMale = self~newRadioButton(IDC_RB_MALE_B)
|
|
rbFemale = self~newRadioButton(IDC_RB_FEMALE_B)
|
|
chkMarried = self~newCheckBox(IDC_CHK_MARRIED_B)
|
|
chkFullTime = self~newCheckBox(IDC_CHK_FULLTIME_B)
|
|
editName = self~newEdit(IDC_EDIT_NAME_B)
|
|
|
|
self~empView = .EmployeeView~new(editName, cbCity, lbPosition, rbMale, rbFemale, chkMarried, chkFullTime)
|
|
|
|
upDown = self~newUpDown(IDC_UPD)
|
|
pbPrint = self~newPushButton(IDC_PB_PRINT_B)
|
|
|
|
|
|
::method noRecord private
|
|
use strict arg direction
|
|
return MessageDialog('At the' direction 'of the records', self~hwnd, -
|
|
'Employee Records')
|
|
|
|
|
|
::method updateUpdown private
|
|
expose pbPrint upDown
|
|
|
|
if self~empCount < 1 then do
|
|
upDown~setRange(0, 0)
|
|
upDown~setPosition(0)
|
|
upDown~disable
|
|
pbPrint~disable
|
|
self~empView~blank
|
|
end
|
|
else do
|
|
upDown~enable
|
|
upDown~setRange(1, self~empCount)
|
|
upDown~setPosition(self~empIndex)
|
|
pbPrint~enable
|
|
self~empView~displayEmployee(self~employees[self~empIndex])
|
|
end
|
|
|
|
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*\
|
|
EmployeeList - A dialog class for a page in the PropertySheetDialog. This
|
|
page allows the user to look at multiple employee records in
|
|
one view.
|
|
\* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
|
::class 'EmployeeList' subclass RcPSPDialog
|
|
|
|
::attribute employees
|
|
::attribute empCount
|
|
::attribute empIndex
|
|
|
|
::method configure
|
|
expose contextMenu
|
|
use arg employees, count, index
|
|
|
|
self~employees = employees
|
|
self~empCount = count
|
|
self~empIndex = index
|
|
|
|
self~connectListViewEvent(IDC_LV_EMPLOYEES, "SELECTCHANGED", onSelectionChanged)
|
|
|
|
mb = .ScriptMenuBar~new(.application~srcDir'employee11tab.rc', IDM_CONTEXT_MENUBAR)
|
|
contextMenu = mb~getPopup(IDM_POP_CONTEXT)
|
|
|
|
::method newEmployeeNotify
|
|
expose lv
|
|
|
|
emp = self~employees[self~empIndex]
|
|
self~addEmployeeRow(lv, emp)
|
|
|
|
self~ensureSelection
|
|
|
|
|
|
::method editedEmployeeNotify
|
|
expose lv
|
|
|
|
emp = self~employees[self~empIndex]
|
|
index = self~empIndex - 1
|
|
|
|
gender = 'Male'
|
|
if \ emp~male then gender = 'Female'
|
|
|
|
mStatus = 'Married'
|
|
if \ emp~married then mStatus = 'Unmarried'
|
|
|
|
eStatus = 'Full Time'
|
|
if \ emp~fullTime then eStatus = 'Part Time'
|
|
|
|
lv~setItemText(index, 0, emp~name)
|
|
lv~setItemText(index, 1, emp~city)
|
|
lv~setItemText(index, 2, emp~position)
|
|
lv~setItemText(index, 3, gender)
|
|
lv~setItemText(index, 4, mStatus)
|
|
lv~setItemText(index, 5, eStatus)
|
|
|
|
self~ensureSelection
|
|
|
|
|
|
::method initDialog
|
|
expose lv contextMenu
|
|
|
|
lv = self~newListView(IDC_LV_EMPLOYEES)
|
|
|
|
lv~addExtendedStyle('CHECKBOXES GRIDLINES FULLROWSELECT')
|
|
|
|
lv~insertColumn(0, "Name", 50)
|
|
lv~insertColumn(1, "City", 40)
|
|
lv~insertColumn(2, "Position", 40)
|
|
lv~insertColumn(3, "Gender", 30)
|
|
lv~insertColumn(4, "Marital Status", 30)
|
|
lv~insertColumn(5, "Employment Classification", 40)
|
|
|
|
do i = 1 to self~empCount
|
|
self~addEmployeeRow(lv, self~employees[i])
|
|
end
|
|
|
|
self~ensureSelection
|
|
|
|
contextMenu~assignTo(self, .true)
|
|
contextMenu~connectContextMenu(onContext, lv~hwnd)
|
|
|
|
|
|
::method onSelectionChanged unguarded
|
|
use arg id, itemIndex, state
|
|
|
|
if state == 'SELECTED' then do
|
|
self~propSheet~selectedEmployeeNotify(itemIndex + 1)
|
|
end
|
|
|
|
|
|
::method setActive unguarded
|
|
expose lv
|
|
|
|
self~ensureSelection
|
|
return 0
|
|
|
|
|
|
::method onContext
|
|
expose contextMenu lv
|
|
use arg hwnd, x, y
|
|
|
|
if x == -1, y == -1 then do
|
|
-- The keyboard was used, not the mouse. Position the context menu
|
|
-- towards the bottom right corner of the list view.
|
|
rect = lv~windowRect
|
|
x = rect~right - .SM~cxVScroll - 15
|
|
y = rect~bottom - 15
|
|
|
|
pos = .Point~new(x, y)
|
|
end
|
|
else do
|
|
pos = .Point~new(x, y)
|
|
|
|
p = pos~copy
|
|
lv~screen2client(p)
|
|
index = lv~hitTestInfo(p)
|
|
|
|
if index == -1 then do
|
|
contextMenu~disable(.array~of(IDM_EDIT, IDM_DELETE))
|
|
self~ensureSelection
|
|
end
|
|
end
|
|
|
|
ret = contextMenu~show(pos)
|
|
|
|
return 0
|
|
|
|
::method browseEmployees unguarded
|
|
self~propSheet~setCurSel( , 3)
|
|
return 0
|
|
|
|
::method addEmployee unguarded
|
|
self~propSheet~setCurSel( , 1)
|
|
return 0
|
|
|
|
::method editEmployee unguarded
|
|
self~propSheet~setCurSel( , 2)
|
|
return 0
|
|
|
|
::method deleteEmployee unguarded
|
|
self~propSheet~maybeDeleteEmployee
|
|
return 0
|
|
|
|
::method deleteEmployeeNotify unguarded
|
|
expose lv
|
|
use strict arg index
|
|
|
|
lv~delete(index - 1)
|
|
self~ensureSelection
|
|
|
|
return 0
|
|
|
|
::method ensureSelection private
|
|
expose lv
|
|
|
|
index = self~empIndex - 1
|
|
if index < 0 then index = 0
|
|
lv~select(index)
|
|
lv~focus(index)
|
|
|
|
return 0
|
|
|
|
|
|
::method addEmployeeRow private
|
|
use strict arg list, employee
|
|
|
|
gender = 'Male'
|
|
if \ employee~male then gender = 'Female'
|
|
|
|
mStatus = 'Married'
|
|
if \ employee~married then mStatus = 'Unmarried'
|
|
|
|
eStatus = 'Full Time'
|
|
if \ employee~fullTime then eStatus = 'Part Time'
|
|
|
|
e = employee
|
|
list~addRow( , , e~name, e~city, e~position, gender, mStatus, eStatus)
|
|
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*\
|
|
Employee - A class that reflects a single, specific, employee.
|
|
\* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
|
::class 'Employee'
|
|
|
|
::attribute name
|
|
::attribute city
|
|
::attribute position
|
|
::attribute male
|
|
::attribute married
|
|
::attribute fullTime
|
|
|
|
::method init
|
|
expose name city position male married fullTime
|
|
use strict arg name = "", city = "New York", position = "Software Developer", -
|
|
male = .true, married = .false, fullTime = .true
|
|
|
|
::method isValid
|
|
expose name
|
|
return name \== ''
|
|
|
|
|
|
::method print
|
|
expose name city position male married fullTime
|
|
use strict arg dlg
|
|
|
|
eol = .endOfLine
|
|
tab = '09'x
|
|
|
|
if \ self~isValid then do
|
|
title = "Acme Software - Internal Error Detected"
|
|
msg = "Attempting to print invalid employee record." || eol~copies(2) -
|
|
"Employee record has no assigned name."
|
|
icon = 'ERROR'
|
|
end
|
|
else do
|
|
title = "Acme Software - Employee:"
|
|
|
|
if male then msg = "Mr." name
|
|
else msg = "Ms." name
|
|
|
|
if married then msg ||= " (married) "
|
|
|
|
msg ||= eol
|
|
|
|
if fullTime then status = 'Full Time Employee'
|
|
else status = 'Part Time Employee'
|
|
|
|
msg ||= eol || "City:" || tab~copies(2) || city || eol || -
|
|
"Profession:" || tab || position || eol || -
|
|
'Status:' || tab~copies(2) || status
|
|
|
|
icon = 'INFORMATION'
|
|
end
|
|
|
|
j = MessageDialog(msg, dlg~hwnd, title, , icon)
|
|
|
|
|
|
::method toCSV
|
|
expose name city position male married fullTime
|
|
use strict arg
|
|
|
|
if male then mf = "M"
|
|
else mf = "F"
|
|
|
|
if married then mu = "M"
|
|
else mu = 'U'
|
|
|
|
if fullTime then fp = 'F'
|
|
else fp = 'P'
|
|
|
|
txt = name', 'city', 'position', 'mf', 'mu', 'fp
|
|
|
|
return txt
|
|
|
|
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*\
|
|
EmployeeView - A class containing the dialog controls used to display an
|
|
employee in a dialog.
|
|
\* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
|
::class 'EmployeeView' public
|
|
|
|
::attribute editName
|
|
::attribute cbCity
|
|
::attribute lbPosition
|
|
::attribute rbMale
|
|
::attribute rbFemale
|
|
::attribute chkMarried
|
|
::attribute chkFullTime
|
|
|
|
::method init
|
|
expose editName cbCity lbPosition rbMale rbFemale chkMarried chkFullTime
|
|
use strict arg editName, cbCity, lbPosition, rbMale, rbFemale, chkMarried, chkFullTime
|
|
|
|
/** fillBoxes()
|
|
* Fills the city combo box and the position list box with the correct items.
|
|
*/
|
|
::method fillBoxes
|
|
expose cbCity lbPosition
|
|
use strict arg
|
|
|
|
cbCity~add("Munich")
|
|
cbCity~add("New York")
|
|
cbCity~add("San Francisco")
|
|
cbCity~add("Stuttgart")
|
|
cbCity~add("San Diego")
|
|
cbCity~add("Tucson")
|
|
cbCity~add("Houston")
|
|
cbCity~add("Los Angeles")
|
|
|
|
lbPosition~add("Business Manager")
|
|
lbPosition~add("Engineering Manager")
|
|
lbPosition~add("Software Developer")
|
|
lbPosition~add("Software QA")
|
|
lbPosition~add("Accountant")
|
|
lbPosition~add("Security")
|
|
lbPosition~add("Secretary")
|
|
lbPosition~add("Recptionist")
|
|
lbPosition~add("Lab Manager")
|
|
lbPosition~add("Lawyer")
|
|
lbPosition~add("CEO")
|
|
|
|
|
|
/** displayEmployee()
|
|
* Sets the state of the controls to reflect the specified employee
|
|
*/
|
|
::method displayEmployee
|
|
use strict arg emp
|
|
|
|
self~editName~setText(emp~name)
|
|
self~cbCity~select(emp~City)
|
|
self~lbPosition~select(emp~Position)
|
|
|
|
if emp~male then do
|
|
self~rbMale~check
|
|
self~rbFemale~uncheck
|
|
end
|
|
else do
|
|
self~rbFemale~check
|
|
self~rbMale~uncheck
|
|
end
|
|
|
|
if emp~married then self~chkMarried~check
|
|
else self~chkMarried~uncheck
|
|
|
|
if emp~fullTime then self~chkFullTime~check
|
|
else self~chkFullTime~uncheck
|
|
|
|
|
|
/** disable()
|
|
* Disables all the controls and sets the edit control text to the empty string.
|
|
*/
|
|
::method disable
|
|
use strict arg
|
|
|
|
self~editName~setText("")
|
|
|
|
self~editName~disable
|
|
self~cbCity~disable
|
|
self~lbPosition~disable
|
|
|
|
self~rbMale~disable
|
|
self~rbFemale~disable
|
|
self~chkMarried~disable
|
|
self~chkFullTime~disable
|
|
|
|
|
|
/** blank()
|
|
* Sets all the controls to a 'blank' state.
|
|
*/
|
|
::method blank
|
|
use strict arg
|
|
|
|
self~editName~setText("")
|
|
--self~cbCity~
|
|
self~lbPosition~deselectIndex
|
|
|
|
self~rbMale~uncheck
|
|
self~rbFemale~uncheck
|
|
self~chkMarried~uncheck
|
|
self~chkFullTime~uncheck
|
|
|
|
|
|
/** match()
|
|
* Tests if the state of the controls match the specified employee.
|
|
*/
|
|
::method sameAs
|
|
use strict arg emp
|
|
|
|
if self~editName~getText \== emp~name then return .false
|
|
if self~cbCity~selected \== emp~City then return .false
|
|
if self~lbPosition~selected \== emp~Position then return .false
|
|
|
|
if self~rbMale~checked & \ emp~male then return .false
|
|
if \ self~rbMale~checked & emp~male then return .false
|
|
|
|
if self~chkMarried~checked & \ emp~married then return .false
|
|
if \ self~chkMarried~checked & emp~married then return .false
|
|
|
|
if self~chkFullTime~checked & \ emp~fullTime then return .false
|
|
if \ self~chkFullTime~checked & emp~fullTime then return .false
|
|
|
|
return .true
|
|
|
|
/** createEmployee()
|
|
* Instantiates a new Employee object using the current state of the controls,
|
|
* and returns it if it is valid. If it is not valid, returns .nil
|
|
*/
|
|
::method createEmployee
|
|
use strict arg
|
|
|
|
name = self~editName~getText~strip
|
|
city = self~cbCity~selected
|
|
position = self~lbPosition~selected
|
|
male = self~rbMale~checked
|
|
married = self~chkMarried~checked
|
|
fullTime = self~chkFullTime~checked
|
|
|
|
emp = .Employee~new(name, city, position, male, married, fullTime)
|
|
|
|
if emp~isValid then return emp
|
|
else return .nil
|
|
|
|
|