dataArray3Fields.length){ trace("DataGridApp.mxml, setUpDataArray3Columns(): numCols is " + numCols.toString() + ", changing to " + dataArray3Fields.length.toString()); numCols = dataArray3Fields.length; } colArray = new Array(); for(i = 0; i < numCols; ++i){ col = new DataGridColumn(); if(backwards) col.dataField = dataArray3Fields[dataArray3Fields.length - 1 - i]; else col.dataField = dataArray3Fields[i]; if(resizableColumns) col.resizable = true; else col.resizable = false; if(useBGColors){ bgColor += 10500; col.setStyle("backgroundColor", bgColor); } colArray.push(col); } dg.columns = colArray; } /** * This will rearrange the columns of the * DataGrid provided. **/ public function rearrangeDataArray3Columns(dg:DataGrid):void{ var col:DataGridColumn; var i:int; colArray = new Array(); for(i = dg.columns.length - 1; i >= 0; --i){ col = new DataGridColumn(); col.dataField = dataArray3Fields[i]; colArray.push(col); } dg.columns = colArray; } /** * This will duplicate the columns of the * DataGrid provided. **/ public function duplicateDataArray3Columns(dg:DataGrid):void{ var col:DataGridColumn; var i:int; var j:int; colArray = new Array(); for(i = 0; i < dg.columns.length; ++i){ for(j = 0; j < 2; ++j){ col = new DataGridColumn(); col.dataField = dataArray3Fields[i]; colArray.push(col); } } dg.columns = colArray; } /************************************************************ * Functions regarding itemEdit *************************************************************/ /** * This function allows you to specify what's going to happen * when ItemEditBegin occurs. * useEditor: The custom editor (a ComboBox) will be used. * Using false = the default, a TextInput. * usePosition: Whether to create the editor at the specified col and row. * Using false = the column and row from the event. * col: The column. Using -1 = the column from the event. * row: The row. Using -1 = the column from the event. **/ public function setUpItemEditBegin(dg:DataGrid, useEditor:Boolean = false, usePosition:Boolean = false, col:int = -1, row:int = -1 ):void{ useCustomEditor = useEditor; useCustomPosition = usePosition; customCol = col; customRow = row; dg.addEventListener(mx.events.DataGridEvent.ITEM_EDIT_BEGIN, doItemEditBegin); } /** * This function allows you to specify what's going to happen * when ItemEditEnd occurs. Right now, it just sets up a * listener to call our custom method. **/ public function setUpItemEditEnd(dg:DataGrid):void{ dg.addEventListener(mx.events.DataGridEvent.ITEM_EDIT_END, doItemEditEnd); } /** * I would like to have put this in datagrid_methods.mxml, but * we want to keep the custom components consolidated in a subdir * of the SWFs directory, and I couldn't figure out how to refer * to a custom control in ../SWFs/comps from a file in the Methods * directory. Maybe it will be handy here when we get to testing * events. * See setUpItemEditBegin for descriptions of the useCustomPosition, * etc... variables. We dispatch an event at the end so that * Mustella will have something to listen for. **/ public function doItemEditBegin(e:DataGridEvent):void{ var column:int; var row:int; column = (useCustomPosition && customCol >= 0) ? customCol : e.columnIndex; row = (useCustomPosition && customRow >= 0) ? customRow : e.rowIndex; e.preventDefault(); if(useCustomEditor) dg1.columns[column].itemEditor = new ClassFactory(comps.CustomEditor); dg1.createItemEditor(column, row); } /** * This is a custom handler for the itemEditEnd event. **/ public function doItemEditEnd(e:DataGridEvent):void{ e.preventDefault(); dg1.destroyItemEditor(); } /************************************************************ * Functions regarding the data provider *************************************************************/ /** * Use this function to reset the dataProvider. Do * not just re-use the dataProvider that is in the * main app. file because edits made to the DataGrid * will continue to appear in subsequent tests. Instead, * use that one as a template to populate this one * which we reset all the time. * Passing in no int will default to 1 because a lot of test cases * were already written before a parameter could be passed in. **/ public function setDataProvider(dg:DataGrid, dpNum:int = 1):void{ switch(dpNum){ case 1: dg.dataProvider = ObjectUtil.copy(dataArray1); break; case 2: dg.dataProvider = ObjectUtil.copy(dataArray2); break; case 3: dg.dataProvider = ObjectUtil.copy(dataArray3); break; case 4: dg.dataProvider = ObjectUtil.copy(dataArray4); break; case 5: dg.dataProvider = [1, 2, 3]; break; case 6: dg.dataProvider = ObjectUtil.copy(dataArray6); break; case 7: dg.dataProvider = ObjectUtil.copy(dataArray7); break; } } /** * Use this function to add a new object to the dataProvider * of a DataGrid which is using the indicated dataArray. **/ public function addNewDataArrayItems(dg:DataGrid, dataArray:int, numAdditions:int):void{ var obj:Object = new Object(); var i:int; switch(dataArray){ case 1: for(i = 0; i < numAdditions; ++i){ obj.fieldA = "cellA" + (18 + i).toString(); obj.fieldB = "cellB" + (18 + i).toString(); obj.fieldC = "cellC" + (18 + i).toString(); obj.fieldD = "cellD" + (18 + i).toString(); obj.fieldE = "cellE" + (18 + i).toString(); obj.recordName = "Record name # " + (18 + i).toString(); obj.recordAmount = "Record amount " + (18 + i).toString(); obj.who = "Person " + (18 + i).toString(); obj.where = "Location " + (18 + i).toString(); obj.when = "Date " + (18 + i).toString(); obj.image = "Image location " + (18 + i).toString(); dg.dataProvider.addItem(obj); } break; default: break; } } /** * Given an ICollectionView and some other info., finds * and replaces the provided string in the provided field. * This is used, for example, in datagrid_properties_dataProvider.mxml, * in test case dataProvider_binding_change. **/ public function changeData(view:ICollectionView, sortFields:Array, editMe:Object, fieldName:String, newVal:String):void{ var sort:Sort = new Sort(); var cursor:IViewCursor = view.createCursor(); var foundObj:Object; sort.fields = sortFields; view.sort = sort; view.refresh(); cursor.findFirst(editMe); foundObj = cursor.current; for(var obj:Object in foundObj){ var propName:String = obj as String; if(propName == fieldName){ foundObj[propName] = newVal; } } } /************************************************************ * Functions regarding filtering *************************************************************/ /** * This applies the filter function "filterStringStartsWithM". **/ public function applyFilterFunctionM(lcv:ListCollectionView):void{ lcv.filterFunction = filterStringEndsWithM; lcv.refresh(); } /** * This removes any filter function that may be present. **/ public function removeFilterFunctionM(lcv:ListCollectionView):void{ lcv.filterFunction = null; lcv.refresh(); } /** * This is a filter function. **/ private function filterStringStartsWithM(item:Object):Boolean{ var ret:Boolean = false; var s:String; try{ s = item.name; if( s.charAt(0).toLowerCase() == "m" ) ret = true; }catch(e:Error){ trace(e); } return ret; } /** * This is a filter function. **/ private function filterStringEndsWithM(item:Object):Boolean{ var ret:Boolean = false; var s:String; try{ s = item.name; if( s.charAt(s.length-1).toLowerCase() == "m" ) ret = true; }catch(e:Error){ trace(e); } return ret; } /************************************************************ * Functions regarding drag and drop *************************************************************/ /** * This will set up the given DataGrid for drag and * drop using doDragEnter1() and doDragDrop1(). **/ public function setUpDragDropListeners1(dg:DataGrid):void{ dg.addEventListener(mx.events.DragEvent.DRAG_ENTER, doDragEnter1); dg.addEventListener(mx.events.DragEvent.DRAG_DROP, doDragDrop1); } /* * This is called upon the dragEnter event of a * DataGrid that is being dragged to. */ private function doDragEnter1(event:DragEvent):void { var dragInitiator:DataGrid=DataGrid(event.currentTarget); DragManager.acceptDragDrop(dragInitiator); } /* * This is called upon the dragDrop event of a * DataGrid that is being dragged to. It assumes * the use of dataArray3 or dataArray4. */ private function doDragDrop1(event:DragEvent):void { var dropTarget:DataGrid=DataGrid(event.currentTarget); var items:Array = event.dragSource.dataForFormat("items") as Array; var dropLoc:int = dropTarget.calculateDropIndex(event); for(var i:uint=0; i < items.length; i++) { var newObj:Object = new Object(); var oldObj:Object = items[i]; newObj.name = oldObj.name; newObj.family = oldObj.family; newObj.age = oldObj.age; newObj.hobby = oldObj.hobby; newObj.thoughts = oldObj.thoughts; IList(dropTarget.dataProvider).addItemAt(newObj, dropLoc); } } /************************************************************ * Functions regarding a WaitForEvent step: * These items are a workaround so that we will be able to listen for * a number of events before continuing. To use: * Call initializeWaitForEvents with the number of events needed, * the event, and the event dispatcher (the DataGrid, for example). * When the correct number of events has occurred, it * will dispatch a new event ('waitForEventsFinished'). The next step * of your test case should be waiting for this event. *************************************************************/ public function initializeWaitForEvents(eventsNeeded:int, event:String, dispatcher:EventDispatcher):void{ waitForEventsCount = 0; waitForEventsNeeded = eventsNeeded; waitForEventsDispatcher = dispatcher; waitForEventsDispatcher.addEventListener(event, waitForEventsFunction); } public function waitForEventsFunction(e:Event):void{ ++waitForEventsCount; if(waitForEventsCount >= waitForEventsNeeded){ waitForEventsDispatcher.dispatchEvent(new Event('waitForEventsFinished')); } } /************************************************************ * Functions regarding label function *************************************************************/ /* * This is a very basic labelFunction function. It doesn't matter * what the source data provider is. */ public function basicLabelFunction(item:Object, column:DataGridColumn):String { return "column: " + column.headerText + ", data: " + item.toString(); } /************************************************************ * Functions regarding sorting *************************************************************/ public function sortTestFunction(event:DataGridEvent):void { var dg:DataGrid = DataGrid(event.target); var dgc:DataGridColumn = dg.columns[event.columnIndex] as DataGridColumn; var s:Sort = new Sort(); var sf:SortField = new SortField(dgc.dataField); var dp:ICollectionView = dg.dataProvider as ICollectionView; event.preventDefault(); sf.descending = !dgc.sortDescending; if(dgc.headerText == "numeric") sf.numeric = true; else if(dgc.headerText == "alpha") sf.numeric = false; else sf.numeric = null; dgc.sortDescending = sf.descending; s.fields = [ sf ]; dp.sort = s; dp.refresh(); } ]]> @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/mx"; @font-face { src: url("../../../../../Assets/Fonts/PT_Serif/PT_Serif-Web-Regular.ttf"); fontFamily: EmbeddedArial; embedAsCFF: false; } @font-face { src: url("../../../../../Assets/Fonts/PT_Serif/PT_Serif-Web-Bold.ttf"); fontWeight: bold; fontFamily: EmbeddedArial; embedAsCFF: false; } @font-face { src: url("../../../../../Assets/Fonts/PT_Serif/PT_Serif-Web-Italic.ttf"); fontStyle: italic; fontFamily: EmbeddedArial; embedAsCFF: false; } @font-face { src: url("../../../../../Assets/Fonts/Open_Sans/OpenSans-Regular.ttf"); fontFamily: EmbeddedVerdana; embedAsCFF: false; } @font-face { src: url("../../../../../Assets/Fonts/Open_Sans/OpenSans-Bold.ttf"); fontWeight: bold; fontFamily: EmbeddedVerdana; embedAsCFF: false; } @font-face { src: url("../../../../../Assets/Fonts/Open_Sans/OpenSans-Italic.ttf"); fontStyle: italic; fontFamily: EmbeddedVerdana; embedAsCFF: false; } @font-face { src: url("../../../../../Assets/Fonts/Cousine/Cousine-Regular.ttf"); fontFamily: EmbeddedComic; embedAsCFF: false; } global{ fontFamily: EmbeddedVerdana; fontAntiAliasType: normal; } .redText { color: #DD0000; fontSize: 14; } .italicText { fontStyle: "italic"; } .boldBig { fontSize: 16; textDecoration: "underline"; }