Index: lams_central/src/flash/org/lamsfoundation/lams/wizard/Application.as =================================================================== diff -u --- lams_central/src/flash/org/lamsfoundation/lams/wizard/Application.as (revision 0) +++ lams_central/src/flash/org/lamsfoundation/lams/wizard/Application.as (revision f44b6a75a25937117bdb05ed3923f868ecbeb587) @@ -0,0 +1,561 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ************************************************************************ + */ + +import org.lamsfoundation.lams.wizard.*; // Wizard + +import org.lamsfoundation.lams.common.ws.* //Workspace +import org.lamsfoundation.lams.common.comms.* //communications +import org.lamsfoundation.lams.common.util.* //Utils +import org.lamsfoundation.lams.common.dict.* //Dictionary +import org.lamsfoundation.lams.common.ui.* //User interface +import org.lamsfoundation.lams.common.style.* //Themes/Styles +import org.lamsfoundation.lams.common.* +import mx.managers.* +import mx.utils.* + +/** +* Application - Adding new sequence - LAMS Monitor (wizard) +* @author M Seaton +*/ +class org.lamsfoundation.lams.wizard.Application extends ApplicationParent { + + + private static var SHOW_DEBUGGER:Boolean = false; + + private static var _controlKeyPressed:String; + + private static var WIZARD_X:Number = 0; + private static var WIZARD_Y:Number = 0; + private static var WIZARD_W:Number = 550; + private static var WIZARD_H:Number = 550; + + private static var APP_ROOT_DEPTH:Number = 10; //depth of the application root + private static var DIALOGUE_DEPTH:Number = 20; //depth of the cursors + private static var TOOLTIP_DEPTH:Number = 30; //depth of the cursors + private static var CURSOR_DEPTH:Number = 40; //depth of the cursors + + private static var UI_LOAD_CHECK_INTERVAL:Number = 50; + private static var UI_LOAD_CHECK_TIMEOUT_COUNT:Number = 200; + private static var DATA_LOAD_CHECK_INTERVAL:Number = 50; + private static var DATA_LOAD_CHECK_TIMEOUT_COUNT:Number = 200; + + private static var QUESTION_MARK_KEY:Number = 191; + private static var X_KEY:Number = 88; + private static var C_KEY:Number = 67; + private static var D_KEY:Number = 68; + //private static var T_KEY:Number = 84; + private static var V_KEY:Number = 86; + private static var Z_KEY:Number = 90; + private static var Y_KEY:Number = 89; + + + + private var _uiLoadCheckCount = 0; // instance counter for number of times we have checked to see if theme and dict are loaded + private var _dataLoadCheckCount = 0; + + private var _wizard:Wizard; + private var _workspace:Workspace; + private var _comms:Communication; + private var _themeManager:ThemeManager; + private var _dictionary:Dictionary; + private var _config:Config; + private var _debugDialog:MovieClip; //Reference to the debug dialog + + + private var _dialogueContainer_mc:MovieClip; //Dialog container + private var _tooltipContainer_mc:MovieClip; //Tooltip container + private var _cursorContainer_mc:MovieClip; //Cursor container + private var _container_mc:MovieClip; //Main container + + //Data flags + private var _dictionaryLoaded:Boolean; //Dictionary loaded flag + private var _dictionaryEventDispatched:Boolean //Event status flag + private var _themeLoaded:Boolean; //Theme loaded flag + private var _themeEventDispatched:Boolean //Dictionary loaded flag + private var _UILoadCheckIntervalID:Number; //Interval ID for periodic check on UILoad status + private var _UILoaded:Boolean; //UI Loading status + + private var _DataLoadCheckIntervalID:Number; + + //UI Elements + //private var _toolbarLoaded:Boolean; //These are flags set to true when respective element is 'loaded' + private var _wizardLoaded:Boolean; + private var _showCMItem:Boolean; + + //clipboard + private var _clipboardData:Object; + // set up Key Listener + //private var keyListener:Object; + + //Application instance is stored as a static in the application class + private static var _instance:Application = null; + + /** + * Application - Constructor + */ + private function Application(){ + super(this); + + // loaded flag + } + + /** + * Retrieves an instance of the Application singleton + */ + public static function getInstance():Application{ + if(Application._instance == null){ + Application._instance = new Application(); + } + return Application._instance; + } + + /** + * Main entry point to the application + */ + public function main(container_mc:MovieClip){ + _container_mc = container_mc; + _UILoaded = false; + + //add the cursors: + Cursor.addCursor(C_HOURGLASS); + + + //Comms object - do this before any objects are created that require it for server communication + _comms = new Communication(); + + //Get the instance of config class + _config = Config.getInstance(); + + //Assign the config load event to + _config.addEventListener('load',Delegate.create(this,configLoaded)); + + //Set up Key handler + //TODO take out after testing and uncomment same key handler in ready(); + Key.addListener(this); + //setupUI(); + //setupData(); + //checkDataLoaded(); + } + + /** + * Called when the config class has loaded + */ + private function configLoaded(){ + //Now that the config class is ready setup the UI and data, call to setupData() first in + //case UI element constructors use objects instantiated with setupData() + setupData(); + checkDataLoaded(); + + } + + /** + * Loads and sets up event listeners for Theme, Dictionary etc. + */ + private function setupData() { + + //Get the language, create+load dictionary and setup load handler. + var language:String = String(_config.getItem('language')); + _dictionary = Dictionary.getInstance(); + _dictionary.addEventListener('load',Delegate.create(this,onDictionaryLoad)); + _dictionary.load(language); + + + + //Set reference to StyleManager and load Themes and setup load handler. + var theme:String = String(_config.getItem('theme')); + _themeManager = ThemeManager.getInstance(); + _themeManager.addEventListener('load',Delegate.create(this,onThemeLoad)); + _themeManager.loadTheme(theme); + Debugger.getInstance().crashDumpSeverityLevel = Number(_config.getItem('crashDumpSeverityLevelLog')); + Debugger.getInstance().severityLevel = Number(_config.getItem('severityLevelLog')); + + } + + /** + * Called when Dictionary loaded + * @param evt:Object the event object + */ + private function onDictionaryLoad(evt:Object){ + if(evt.type=='load'){ + _dictionaryLoaded = true; + Debugger.log('Dictionary loaded :',Debugger.CRITICAL,'onDictionaryLoad','Application'); + } else { + Debugger.log('event type not recognised :'+evt.type,Debugger.CRITICAL,'onDictionaryLoad','Application'); + } + } + + /** + * Called when the current selected theme has been loaded + * @param evt:Object the event object + */ + private function onThemeLoad(evt:Object) { + if(evt.type=='load'){ + _themeLoaded = true; + Debugger.log('!Theme loaded :',Debugger.CRITICAL,'onThemeLoad','Application'); + } else { + Debugger.log('event type not recognised :'+evt.type,Debugger.CRITICAL,'onThemeLoad','Application'); + } + + } + + /** + * Periodically checks if data has been loaded + */ + private function checkDataLoaded() { + // first time through set interval for method polling + if(!_DataLoadCheckIntervalID) { + _DataLoadCheckIntervalID = setInterval(Proxy.create(this, checkDataLoaded), DATA_LOAD_CHECK_INTERVAL); + } else { + _dataLoadCheckCount++; + // if dictionary and theme data loaded setup UI + if(_dictionaryLoaded && _themeLoaded) { + clearInterval(_DataLoadCheckIntervalID); + + setupUI(); + checkUILoaded(); + + + } else if(_dataLoadCheckCount >= DATA_LOAD_CHECK_TIMEOUT_COUNT) { + Debugger.log('reached timeout waiting for data to load.',Debugger.CRITICAL,'checkUILoaded','Application'); + clearInterval(_UILoadCheckIntervalID); + + + } + } + } + + /** + * Runs periodically and dispatches events as they are ready + */ + private function checkUILoaded() { + //If it's the first time through then set up the interval to keep polling this method + if(!_UILoadCheckIntervalID) { + _UILoadCheckIntervalID = setInterval(Proxy.create(this,checkUILoaded),UI_LOAD_CHECK_INTERVAL); + } else { + _uiLoadCheckCount++; + //If all events dispatched clear interval and call start() + if(_dictionaryEventDispatched && _themeEventDispatched){ + //Debugger.log('Clearing Interval and calling start :',Debugger.CRITICAL,'checkUILoaded','Application'); + clearInterval(_UILoadCheckIntervalID); + start(); + }else { + //If UI loaded check which events can be broadcast + if(_UILoaded){ + //Debugger.log('ALL UI LOADED, waiting for all true to dispatch init events: _dictionaryLoaded:'+_dictionaryLoaded+'_themeLoaded:'+_themeLoaded ,Debugger.GEN,'checkUILoaded','Application'); + + //If dictionary is loaded and event hasn't been dispatched - dispatch it + if(_dictionaryLoaded && !_dictionaryEventDispatched){ + _dictionaryEventDispatched = true; + _dictionary.broadcastInit(); + } + //If theme is loaded and theme event hasn't been dispatched - dispatch it + if(_themeLoaded && !_themeEventDispatched){ + _themeEventDispatched = true; + _themeManager.broadcastThemeChanged(); + } + + if(_uiLoadCheckCount >= UI_LOAD_CHECK_TIMEOUT_COUNT){ + //if we havent loaded the dict or theme by the timeout count then give up + Debugger.log('raeached time out waiting to load dict and themes, giving up.',Debugger.CRITICAL,'checkUILoaded','Application'); + var msg:String = ""; + if(!_themeEventDispatched){ + msg+=Dictionary.getValue("app_chk_themeload"); + } + if(!_dictionaryEventDispatched){ + msg+="The lanaguage data has not been loaded."; + } + msg+=Dictionary.getValue("app_fail_continue"); + var e:LFError = new LFError(msg,"Canvas.setDroppedTemplateActivity",this,'_themeEventDispatched:'+_themeEventDispatched+' _dictionaryEventDispatched:'+_dictionaryEventDispatched); + e.showErrorAlert(); + //todo: give the user a message + clearInterval(_UILoadCheckIntervalID); + } + } + } + } + } + + /** + * This is called by each UI element as it loads to notify Application that it's loaded + * When all UIElements are loaded the Application can set UILoaded flag true allowing events to be dispatched + * and methods called on the UI Elements + * + * @param UIElementID:String - Identifier for the Element that was loaded + */ + public function UIElementLoaded(evt:Object) { + if(evt.type=='load'){ + //Which item has loaded + switch (evt.target.className) { + case 'Wizard' : + _wizardLoaded = true; + break; + default: + } + + //If all of them are loaded set UILoad accordingly + if(_wizardLoaded){ + _UILoaded=true; + } + + } + } + + public function showCustomCM(showCMItem:Boolean, cmItems):Object{ + + var root_cm:ContextMenu = new ContextMenu(); + root_cm.hideBuiltInItems(); + trace("CM Item label: "+cmItems.cmlabel) + for (var i=0; i0){ + childNode.attributes.isBranch = true; + createXMLNodes(childNode, nodes[i].nodes); + } else { + childNode.attributes.isBranch = false; + } + + wizardModel.setOrganisationResource(RT_ORG+'_'+odto.organisationID,childNode); + + } + + } + + private function getDataObject(dto:Object):Object{ + var odto= {}; + odto.organisationID = dto.organisationID; + odto.organisationTypeId = dto.organisationTypeId; + odto.description = dto.description; + odto.name = dto.name; + odto.parentID = dto.parentID; + + return odto; + } + + + /** + * Opens a design using workspace and user to select design ID + * passes the callback function to recieve selected ID + */ + public function openDesignByWizard(){ + //Work space opens dialog and user will select view + var callback:Function = Proxy.create(this, openDesignById); + var ws = Application.getInstance().getWorkspace(); + ws.wizardSelectDesign(callback); + } + + /** + * Request design from server using supplied ID. + * @usage + * @param designId + * @return + */ + private function openDesignById(workspaceResultDTO:Object){ + trace('step 1 completed'); + ObjectUtils.toString(workspaceResultDTO); + wizardModel.workspaceResultDTO = workspaceResultDTO; + //var designId:Number = workspaceResultDTO.selectedResourceID; + //var lessonName:String = workspaceResultDTO.resourceName; + //var lessonDesc:String = workspaceResultDTO.resourceDescription; + //var callback:Function = Proxy.create(this,setLesson); + + //Application.getInstance().getComms().getRequest('monitoring/monitoring.do?method=initializeLesson&learningDesignID='+designId+'&userID='+_root.userID+'&lessonName='+lessonName+'&lessonDescription='+lessonDesc,callback, false); + + + } + + public function requestUsers(role:String, orgID:Number, callback:Function){ + Application.getInstance().getComms().getRequest('workspace.do?method=getUsersFromOrganisationByRole&organisationID='+orgID+'&role='+role,callback, false); + + } + + /** + * + * @usage + * @param newonOKCallback + * @return + */ + public function set onOKCallback (newonOKCallback:Function):Void { + _onOKCallBack = newonOKCallback; + } + /** + * + * @usage + * @return + */ + public function get onOKCallback ():Function { + return _onOKCallBack; + } + + /** + * Used by application to set the size + * @param width The desired width + * @param height the desired height + */ + public function setSize(width:Number, height:Number):Void{ + wizardModel.setSize(width, height); + } + + public function setPosition(x:Number,y:Number){ + //Set the position within limits + //TODO DI 24/05/05 write validation on limits + wizardModel.setPosition(x,y); + } + + //Dimension accessor methods + public function get width():Number{ + return wizardModel.width; + } + + public function get height():Number{ + return wizardModel.height; + } + + public function get x():Number{ + return wizardModel.x; + } + + public function get y():Number{ + return wizardModel.y; + } + + function get className():String { + return _className; + } + public function getWM():WizardModel{ + return wizardModel; + } + public function getWV():WizardView{ + return wizardView; + } + + public function set workspaceView(a:WorkspaceView){ + wizardView.workspaceView = a; + } + + public function get workspaceView():WorkspaceView{ + return wizardView.workspaceView; + } + + public function get root():MovieClip{ + return _root_mc; + } +} \ No newline at end of file Index: lams_central/src/flash/org/lamsfoundation/lams/wizard/WizardController.as =================================================================== diff -u --- lams_central/src/flash/org/lamsfoundation/lams/wizard/WizardController.as (revision 0) +++ lams_central/src/flash/org/lamsfoundation/lams/wizard/WizardController.as (revision f44b6a75a25937117bdb05ed3923f868ecbeb587) @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ************************************************************************ + */ + +import org.lamsfoundation.lams.common.mvc.*; +import org.lamsfoundation.lams.common.util.*; +import org.lamsfoundation.lams.wizard.*; +import org.lamsfoundation.lams.common.ws.*; +import mx.utils.* + +/** +* Controller for the sequence library +*/ +class WizardController extends AbstractController { + private var _wizardModel:WizardModel; + private var _wizardController:WizardController; + + /** + * Constructor + * + * @param wm The model to modify. + */ + public function WizardController (wm:Observable) { + super (wm); + _wizardModel = WizardModel(model); + _wizardController = this; + + } + + // add control methods + + + public function click(evt):Void{ + trace(evt.target); + // button click event handler - next, prev, finish, cancel + } + + /** + * Workspace dialog OK button clicked handler + */ + private function okClicked(evt:Object) { + + if(evt.type == 'okClicked'){ + //invalidate the cache of folders + //getView().workspaceView.getModel().clearWorkspaceCache(evt.target.resultDTO.targetWorkspaceFolderID); + + //pass the resultant DTO back to the class that called us. + Application.getInstance().getWorkspace().onOKCallback(evt.target.resultDTO); + + } + } + + /** + * Invoked when the node is opened. it must be a folder + */ + public function onTreeNodeOpen (evt:Object){ + var treeview = evt.target; + var nodeToOpen:XMLNode = evt.node; + Debugger.log('nodeToOpen organisationID:'+nodeToOpen.attributes.data.organisationID,Debugger.GEN,'onTreeNodeOpen','org.lamsfoundation.lams.MonitorController'); + Debugger.log('nodeToOpen org name:'+nodeToOpen.attributes.data.name,Debugger.GEN,'onTreeNodeOpen','org.lamsfoundation.lams.MonitorController'); + //if this ndoe has children then the + //data has already been got, nothing to do + + } + + /** + * Treeview data changed event handler + */ + public function onTreeNodeClose (evt:Object){ + Debugger.log('type::'+evt.type,Debugger.GEN,'onTreeNodeClose','org.lamsfoundation.lams.MonitorController'); + var treeview = evt.target; + } + + public function onTreeNodeChange (evt:Object){ + Debugger.log('type::'+evt.type,Debugger.GEN,'onTreeNodeChange','org.lamsfoundation.lams.MonitorController'); + var treeview = evt.target; + _wizardModel.setSelectedTreeNode(treeview.selectedNode); + } + + private function getView():WizardView{ + return WizardView(super.getView()); + } + +} \ No newline at end of file Index: lams_central/src/flash/org/lamsfoundation/lams/wizard/WizardModel.as =================================================================== diff -u --- lams_central/src/flash/org/lamsfoundation/lams/wizard/WizardModel.as (revision 0) +++ lams_central/src/flash/org/lamsfoundation/lams/wizard/WizardModel.as (revision f44b6a75a25937117bdb05ed3923f868ecbeb587) @@ -0,0 +1,428 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ************************************************************************ + */ + +import org.lamsfoundation.lams.monitoring.*; +import org.lamsfoundation.lams.wizard.*; +import org.lamsfoundation.lams.common.Sequence; +import org.lamsfoundation.lams.common.util.Observable; +import org.lamsfoundation.lams.common.util.*; +import org.lamsfoundation.lams.common.ws.*; +import mx.managers.* +import mx.utils.* +import mx.events.*; + +/* +* Model for the Monitoring Tabs +*/ +class WizardModel extends Observable{ + private var _className:String = "WizardModel"; + + public var RT_FOLDER:String = "Folder"; + public var RT_ORG:String = "Organisation"; + public var RT_LD:String = "LearningDesign"; + + // constants + private static var LEARNER_ROLE:String = "LEARNER"; + private static var STAFF_ROLE:String = "STAFF"; + private static var TEACHER_ROLE:String = "TEACHER"; + + private static var USER_LOAD_CHECK_INTERVAL:Number = 50; + private static var USER_LOAD_CHECK_TIMEOUT_COUNT:Number = 200; + + private var __width:Number; + private var __height:Number; + private var __x:Number; + private var __y:Number; + private var _isDirty:Boolean; + private var infoObj:Object; + + // wizard main + private var _wizard:Wizard; + + + private var _org:Organisation; + private var lessonID:Number; + + // state data + private var _staffLoaded:Boolean; + private var _learnersLoaded:Boolean; + private var _UserLoadCheckIntervalID:Number; //Interval ID for periodic check on User Load status + private var _userLoadCheckCount = 0; // instance counter for number of times we have checked to see if users are loaded + + //this is the dataprovider for the org tree + private var _treeDP:XML; + private var _orgResources:Array; + private var _orgs:Array; + private var _selectedOrgTreeNode:XMLNode; + private var _selectedLocTreeNode:XMLNode; + + private var _workspaceResultDTO:Object; + private var _stepID:Number; + + private var dispatchEvent:Function; + public var addEventListener:Function; + public var removeEventListener:Function; + + /** + * Constructor. + */ + public function WizardModel (wizard:Wizard){ + _wizard = wizard; + + _orgResources = new Array(); + _staffLoaded = false; + _learnersLoaded = false; + + _workspaceResultDTO = new Object(); + _stepID = 1; + + mx.events.EventDispatcher.initialize(this); + } + + // add get/set methods + + public function setOrganisation(org:Organisation){ + _org = org; + + setChanged(); + + //send an update + infoObj = {}; + infoObj.updateType = "ORGANISATION_UPDATED"; + notifyObservers(infoObj); + } + + public function getOrganisation():Organisation{ + return _org; + } + + public function saveOrgs(orgs:Array){ + _orgs = orgs; + } + + public function getOrgs():Array{ + return _orgs; + } + + + public function broadcastViewUpdate(updateType, data){ + //getMonitor().getMV().clearView(); + setChanged(); + + //send an update + infoObj = {}; + infoObj.updateType = updateType; + infoObj.data = data; + notifyObservers(infoObj); + + } + + + /** + * Periodically checks if users have been loaded + */ + private function checkUsersLoaded() { + // first time through set interval for method polling + if(!_UserLoadCheckIntervalID) { + _UserLoadCheckIntervalID = setInterval(Proxy.create(this, checkUsersLoaded), USER_LOAD_CHECK_INTERVAL); + } else { + _userLoadCheckCount++; + // if dictionary and theme data loaded setup UI + if(_staffLoaded && _learnersLoaded) { + clearInterval(_UserLoadCheckIntervalID); + + trace('ALL USERS LOADED -CONTINUE'); + // populate learner/staff scrollpanes + broadcastViewUpdate("USERS_LOADED", null, null); + + + } else if(_userLoadCheckCount >= USER_LOAD_CHECK_TIMEOUT_COUNT) { + Debugger.log('reached timeout waiting for data to load.',Debugger.CRITICAL,'checkUsersLoaded','MonitorModel'); + clearInterval(_UserLoadCheckIntervalID); + } + } + } + + private function resetUserFlags():Void{ + staffLoaded = false; + learnersLoaded = false; + _userLoadCheckCount = 0; + _UserLoadCheckIntervalID = null; + } + + private function requestLearners(data:Object){ + + trace('requesting learners...'); + var callback:Function = Proxy.create(this,saveLearners); + _wizard.requestUsers(LEARNER_ROLE, data.organisationID, callback); + } + + + private function requestStaff(data:Object){ + + trace('requesting staff members...'); + var callback:Function = Proxy.create(this,saveStaff); + + _wizard.requestUsers(STAFF_ROLE, data.organisationID, callback); + } + + public function saveLearners(users:Array){ + trace('retrieving back users for org by role: ' + LEARNER_ROLE); + + saveUsers(users, LEARNER_ROLE); + + dispatchEvent({type:'learnersLoad',target:this}); + } + + public function saveStaff(users:Array){ + trace('retrieving back users for org by role: ' + STAFF_ROLE); + + saveUsers(users, STAFF_ROLE); + + dispatchEvent({type:'staffLoad',target:this}); + } + + private function saveUsers(users:Array, role:String):Void{ + + for(var i=0; i< users.length; i++){ + var u:Object = users[i]; + + var user:User = User(organisation.getUser(u.userID)); + if(user != null){ + trace('adding role to existing user: ' + user.getFirstName() + ' ' + user.getLastName()); + user.addRole(role); + } else { + user = new User(); + user.populateFromDTO(u); + user.addRole(role); + + trace('adding user: ' + user.getFirstName() + ' ' + user.getLastName() + ' ' + user.getUserId()); + organisation.addUser(user); + } + } + } + + public function setDirty(){ + _isDirty = true; + } + + public function setSize(width:Number,height:Number) { + __width = width; + __height = height; + + setChanged(); + + //send an update + infoObj = {}; + infoObj.updateType = "SIZE"; + notifyObservers(infoObj); + } + + /** + * Used by View to get the size + * @returns Object containing width(w) & height(h). obj.w & obj.h + */ + public function getSize():Object{ + var s:Object = {}; + s.w = __width; + s.h = __height; + return s; + } + + /** + * sets the model x + y vars + */ + public function setPosition(x:Number,y:Number):Void{ + //Set state variables + __x = x; + __y = y; + //Set flag for notify observers + setChanged(); + + //build and send update object + infoObj = {}; + infoObj.updateType = "POSITION"; + notifyObservers(infoObj); + } + + /** + * Used by View to get the size + * @returns Object containing width(w) & height(h). obj.w & obj.h + */ + public function getPosition():Object{ + var p:Object = {}; + p.x = __x; + p.y = __y; + return p; + } + + /** + * Sets up the tree for the 1st time + * + * @usage + * @return + */ + public function initOrganisationTree(){ + _treeDP = new XML(); + _orgResources = new Array(); + } + + /** + * + * @usage + * @param neworgResources + * @return + */ + public function setOrganisationResource(key:String,neworgResources:XMLNode):Void { + Debugger.log(key+'='+neworgResources,Debugger.GEN,'setOrganisationResource','org.lamsfoundation.lams.monitoring.mv.MonitorModel'); + _orgResources[key] = neworgResources; + } + /** + * + * @usage + * @return + */ + public function getOrganisationResource(key:String):XMLNode{ + Debugger.log(key+' is returning '+_orgResources[key],Debugger.GEN,'getOrganisationResource','org.lamsfoundation.lams.monitoring.mv.MonitorModel'); + return _orgResources[key]; + + } + + + public function get treeDP():XML{ + return _treeDP; + } + + public function get organisation():Organisation{ + return _org; + } + + /** + * + * @usage + * @param newselectedTreeNode + * @return + */ + public function setSelectedTreeNode (newselectedTreeNode:XMLNode):Void { + _selectedOrgTreeNode = newselectedTreeNode; + trace('branch: ' + _selectedOrgTreeNode.attributes.isBranch); + //if(!_selectedOrgTreeNode.attributes.isBranch){ + // get the organisations (node) users by role + //var roles:Array = new Array(LEARNER_ROLE, STAFF_ROLE, TEACHER_ROLE); + setOrganisation(new Organisation(_selectedOrgTreeNode.attributes.data)); + resetUserFlags(); + // polling method - waiting for all users to load before displaying users in UI + checkUsersLoaded(); + + // load users + requestLearners(_selectedOrgTreeNode.attributes.data); + requestStaff(_selectedOrgTreeNode.attributes.data); + + trace(staffLoaded); + trace(learnersLoaded); + //} + + } + + /** + * + * @usage + * @return + */ + public function getSelectedOrgTreeNode ():XMLNode { + return _selectedOrgTreeNode; + } + + public function get learnersLoaded():Boolean{ + return _learnersLoaded; + } + + public function set learnersLoaded(a:Boolean):Void{ + _learnersLoaded = a; + } + + public function get staffLoaded():Boolean{ + return _staffLoaded; + } + + public function set staffLoaded(a:Boolean):Void{ + _staffLoaded = a; + } + + public function get workspaceResultDTO():Object{ + return _workspaceResultDTO; + } + + public function set workspaceResultDTO(a:Object):Void{ + _workspaceResultDTO = a; + } + + public function get stepID():Number{ + return _stepID; + } + + public function set stepID(a:Number):Void{ + + var obj = new Object(); + obj.lastStep = stepID; + obj.currentStep = a; + + _stepID = obj.currentStep; + + //Set flag for notify observers + setChanged(); + + //build and send update object + infoObj = {}; + infoObj.data = obj; + infoObj.updateType = "STEP_CHANGED"; + notifyObservers(infoObj); + } + + //Accessors for x + y coordinates + public function get x():Number{ + return __x; + } + + public function get y():Number{ + return __y; + } + + //Accessors for x + y coordinates + public function get width():Number{ + return __width; + } + + public function get height():Number{ + return __height; + } + + public function get className():String{ + return 'WizardModel'; + } + + public function getWizard():Wizard{ + return _wizard; + } + +} Index: lams_central/src/flash/org/lamsfoundation/lams/wizard/WizardView.as =================================================================== diff -u --- lams_central/src/flash/org/lamsfoundation/lams/wizard/WizardView.as (revision 0) +++ lams_central/src/flash/org/lamsfoundation/lams/wizard/WizardView.as (revision f44b6a75a25937117bdb05ed3923f868ecbeb587) @@ -0,0 +1,781 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ************************************************************************ + */ +import mx.controls.* +import mx.utils.* +import mx.managers.* +import mx.events.* + +import org.lamsfoundation.lams.common.util.* +import org.lamsfoundation.lams.common.ui.* +import org.lamsfoundation.lams.common.style.* +import org.lamsfoundation.lams.wizard.* +import org.lamsfoundation.lams.monitoring.User; +import org.lamsfoundation.lams.monitoring.Orgnanisation; +import org.lamsfoundation.lams.common.dict.* +import org.lamsfoundation.lams.common.mvc.* +import org.lamsfoundation.lams.common.ws.* + +import it.sephiroth.TreeDnd + + +/** +* Wizard view +* Relects changes in the WizardModel +*/ + +class WizardView extends AbstractView { + + private var _className = "WizardView"; + + //constants + public var RT_ORG:String = "Organisation"; + public static var USERS_X:Number = 10; + public static var USER_OFFSET:Number = 20; + + + private var _wizardView:WizardView; + private var _tm:ThemeManager; + //private var _workspace:Workspace; + + private var _wizardView_mc:MovieClip; + //private var bkg_pnl:MovieClip; + + private var org_treeview:Tree; //Treeview for navigation through workspace folder structure + private var location_treeview:Tree; + + private var _staffList:Array; + private var _learnerList:Array; + private var _learner_mc:MovieClip; + private var _staff_mc:MovieClip; + private var staff_scp:MovieClip; // staff/teachers container + private var staff_lbl:Label; + private var learner_scp:MovieClip; // learners container + private var learner_lbl:Label; + + //private var input_txt:TextInput; + private var currentPath_lbl:Label; + private var title_lbl:Label; + private var resourceTitle_txi:TextInput; + private var desc_lbl:Label; + private var resourceDesc_txa:TextArea; + + //Dimensions for resizing + private var xOkOffset:Number; + private var yOkOffset:Number; + private var xCancelOffset:Number; + private var yCancelOffset:Number; + + private var header_pnl:MovieClip; // top panel base + private var footer_pnl:MovieClip; // bottom panel base + + private var panel:MovieClip; //The underlaying panel base + + // common buttons + private var finish_btn:Button; + private var cancel_btn:Button; + private var next_btn:Button; + private var prev_btn:Button; + + private var _resultDTO:Object; + + private var _wizardController:WizardController; + + private var _workspaceModel:WorkspaceModel; + private var _workspaceView:WorkspaceView; + private var _workspaceController:WorkspaceController; + + //Defined so compiler can 'see' events added at runtime by EventDispatcher + private var dispatchEvent:Function; + public var addEventListener:Function; + public var removeEventListener:Function; + //public var menu:ContextMenu; + + + /** + * Constructor + */ + function WizardView(){ + _wizardView = this; + _tm = ThemeManager.getInstance(); + _resultDTO = new Object(); + //_workspace = Application.getInstance().getWorkspace(); + //Init for event delegation + mx.events.EventDispatcher.initialize(this); + } + + /** + * Called to initialise Canvas . CAlled by the Canvas container + */ + public function init(m:Observable,c:Controller){ + super (m, c); + + currentPath_lbl.text = ""+Dictionary.getValue('ws_dlg_location_button')+":" + + trace('org tree:' + org_treeview); + MovieClipUtils.doLater(Proxy.create(this,draw)); + + } + + /** + * Recieved update events from the WizardModel. Dispatches to relevent handler depending on update.Type + * @usage + * @param event + */ + public function update (o:Observable,infoObj:Object):Void{ + + var wm:WizardModel = WizardModel(o); + _wizardController = getController(); + + switch (infoObj.updateType){ + case 'STEP_CHANGED' : + updateScreen(infoObj.data.lastStep, infoObj.data.currentStep); + break; + case 'USERS_LOADED' : + loadLearners(wm.organisation.getLearners()); + loadStaff(wm.organisation.getStaff()); + break; + case 'POSITION' : + setPosition(wm); + break; + case 'SIZE' : + setSize(wm); + break; + default : + Debugger.log('unknown update type :' + infoObj.updateType,Debugger.CRITICAL,'update','org.lamsfoundation.lams.WizardView'); + } + + } + + /** + * Recieved update events from the WorkspaceModel. Dispatches to relevent handler depending on update.Type + * @usage + * @param event + */ + public function viewUpdate(event:Object):Void{ + trace('receiving view update event...'); + var wm:WorkspaceModel = event.target; + //set a permenent ref to the model for ease (sorry mvc guru) + _workspaceModel = wm; + + switch (event.updateType){ + case 'REFRESH_TREE' : + refreshTree(wm); + break; + case 'UPDATE_CHILD_FOLDER' : + updateChildFolderBranches(event.data,wm); + case 'ITEM_SELECTED' : + itemSelected(event.data,wm); + break; + case 'OPEN_FOLDER' : + openFolder(event.data, wm); + break; + case 'REFRESH_FOLDER' : + refreshFolder(event.data, wm); + break; + case 'SET_UP_BRANCHES_INIT' : + setUpBranchesInit(); + break; + default : + Debugger.log('unknown update type :' + event.updateType,Debugger.GEN,'viewUpdate','org.lamsfoundation.lams.ws.WorkspaceDialog'); + + } + } + + /** + * layout visual elements on the canvas on initialisation + */ + private function draw(){ + + showStep1(); + dispatchEvent({type:'load',target:this}); + + } + + /** + * Called by the wizardController after the workspace has loaded + * @usage + * @return + */ + public function setUpContent():Void{ + trace('setting up content'); + //register to recive updates form the model + WorkspaceModel(workspaceView.getModel()).addEventListener('viewUpdate',this); + var controller = getController(); + this.addEventListener('okClicked',Delegate.create(controller,controller.okClicked)); + next_btn.addEventListener('click',Delegate.create(this, next)); + prev_btn.addEventListener('click',Delegate.create(this, prev)); + finish_btn.addEventListener('click',Delegate.create(this, finish)); + cancel_btn.addEventListener('click',Delegate.create(this, cancel)); + //Set up the treeview + setUpTreeview(); + //itemSelected(location_treeview.selectedNode, WorkspaceModel(workspaceView.getModel())); + + } + + private function itemSelected(newSelectedNode:XMLNode, wm:WorkspaceModel){ + //update the UI with the new info + var nodeData = newSelectedNode.attributes.data; + trace('selected node data: ' + nodeData); + if(nodeData.resourceType == wm.RT_FOLDER){ + resourceTitle_txi.text = ""; + resourceDesc_txa.text = ""; + }else{ + if(nodeData.name == null){ + resourceTitle_txi.text = ""; + } else { + resourceTitle_txi.text = nodeData.name; + } + + if(nodeData.description == null){ + resourceDesc_txa.text = ""; + } else { + resourceDesc_txa.text = nodeData.description; + } + } + + } + + /** + * Recursive function to set any folder with children to be a branch + * TODO: Might / will have to change this behaviour once designs are being returned into the mix + * @usage + * @param node + * @return + */ + private function setBranches(node:XMLNode){ + if(node.hasChildNodes() || node.attributes.isBranch){ + location_treeview.setIsBranch(node, true); + for (var i = 0; i