You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ah...@apache.org on 2018/08/09 00:23:15 UTC
[royale-asjs] branch feature/MXRoyale updated (aa7172b -> 166b8ca)
This is an automated email from the ASF dual-hosted git repository.
aharui pushed a change to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git.
from aa7172b Support for RoyaleClientID (like FlexClientId) in headers to make BlazeDS recognize the current client and make royale work with BlazeDS FlexSession and credentials. Some additional work is done here with readExternal and writeExternal methods, those compile, but are not tested, and sure needs more work, but at least compile. The same for IDataInput and IDataOutput that should replace flash.utils. counterparts
new dc531d7 handle initial sizing
new d4dcbb2 get binding to work
new eaff36c manually copy data file
new 0538884 fix folder name
new f7753d2 need these APIs
new f0dac13 tune up fonts to be more like Flex
new 8a3f7d2 typo
new 48f0770 can't use braces here
new 166b8ca see how much of Flex collections we can reuse. This compiles but will it run?
The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
examples/mxroyale/tourdeflexmodules/build.xml | 2 +
.../src/main/config/compile-js-config.xml | 2 +
.../src/main/config/compile-swf-config.xml | 1 +
.../MXRoyale/src/main/resources/defaults.css | 17 +
.../MXRoyale/src/main/royale/MXRoyaleClasses.as | 3 +
.../main/royale/mx/collections/ArrayCollection.as | 6 +-
.../main/royale/mx/collections/ICollectionView.as | 7 +-
.../src/main/royale/mx/collections/ISort.as | 34 +-
.../src/main/royale/mx/collections/ISortField.as | 544 +--
.../royale/mx/collections/ListCollectionView.as | 3528 ++++++++++++++++----
.../src/main/royale/mx/collections/Sort.as | 1052 ++++--
.../src/main/royale/mx/collections/SortField.as | 1703 +++++-----
.../royale/mx/collections/SortFieldCompareTypes.as | 117 +
.../main/royale/mx/collections/XMLListAdapter.as | 826 +++++
.../royale/mx/collections/XMLListCollection.as | 400 ++-
.../{error/SortError.as => errors/CursorError.as} | 17 +-
.../mx/collections/{error => errors}/SortError.as | 0
.../src/main/royale/mx/controls/TextArea.as | 2 +-
.../MXRoyale/src/main/royale/mx/controls/Tree.as | 58 +-
.../models/SingleSelectionICollectionViewModel.as} | 48 +-
.../beads/models/SingleSelectionIListModel.as} | 18 +-
.../royale/mx/controls/listClasses/ListBase.as | 49 +-
.../controls/treeClasses/DefaultDataDescriptor.as | 779 +++++
.../treeClasses/HierarchicalCollectionView.as | 1125 +++++++
.../controls/treeClasses/HierarchicalViewCursor.as | 982 ++++++
.../mx/controls/treeClasses/ITreeDataDescriptor.as | 76 +
.../controls/treeClasses/ITreeDataDescriptor2.as | 107 +
.../src/main/royale/mx/core/Application.as | 13 +-
.../MXRoyale/src/main/royale/mx/core/Container.as | 7 +-
.../main/royale/mx/core/IPropertyChangeNotifier.as | 97 +
.../mx/{logging/LogEventLevel.as => core/IUID.as} | 37 +-
.../MXRoyale/src/main/royale/mx/errors/EOFError.as | 7 +-
.../src/main/royale/mx/managers/SystemManager.as | 24 +-
.../mx_internal.as => utils/IXMLNotifiable.as} | 22 +-
.../MXRoyale/src/main/royale/mx/utils/UIDUtil.as | 298 ++
.../src/main/royale/mx/utils/XMLNotifier.as | 276 ++
36 files changed, 10136 insertions(+), 2148 deletions(-)
create mode 100644 frameworks/projects/MXRoyale/src/main/royale/mx/collections/SortFieldCompareTypes.as
create mode 100644 frameworks/projects/MXRoyale/src/main/royale/mx/collections/XMLListAdapter.as
copy frameworks/projects/MXRoyale/src/main/royale/mx/collections/{error/SortError.as => errors/CursorError.as} (80%)
rename frameworks/projects/MXRoyale/src/main/royale/mx/collections/{error => errors}/SortError.as (100%)
copy frameworks/projects/{Basic/src/main/royale/org/apache/royale/html/beads/models/SingleSelectionCollectionViewModel.as => MXRoyale/src/main/royale/mx/controls/beads/models/SingleSelectionICollectionViewModel.as} (80%)
copy frameworks/projects/{Basic/src/main/royale/org/apache/royale/html/beads/models/SingleSelectionCollectionViewModel.as => MXRoyale/src/main/royale/mx/controls/beads/models/SingleSelectionIListModel.as} (91%)
create mode 100644 frameworks/projects/MXRoyale/src/main/royale/mx/controls/treeClasses/DefaultDataDescriptor.as
create mode 100644 frameworks/projects/MXRoyale/src/main/royale/mx/controls/treeClasses/HierarchicalCollectionView.as
create mode 100644 frameworks/projects/MXRoyale/src/main/royale/mx/controls/treeClasses/HierarchicalViewCursor.as
create mode 100644 frameworks/projects/MXRoyale/src/main/royale/mx/controls/treeClasses/ITreeDataDescriptor2.as
create mode 100644 frameworks/projects/MXRoyale/src/main/royale/mx/core/IPropertyChangeNotifier.as
copy frameworks/projects/MXRoyale/src/main/royale/mx/{logging/LogEventLevel.as => core/IUID.as} (69%)
copy frameworks/projects/MXRoyale/src/main/royale/mx/{core/mx_internal.as => utils/IXMLNotifiable.as} (74%)
create mode 100644 frameworks/projects/MXRoyale/src/main/royale/mx/utils/UIDUtil.as
create mode 100644 frameworks/projects/MXRoyale/src/main/royale/mx/utils/XMLNotifier.as
[royale-asjs] 05/09: need these APIs
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aharui pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit f7753d2d0ce9c36c1594dda4f4ae2b6fbdf3081f
Author: Alex Harui <ah...@apache.org>
AuthorDate: Tue Aug 7 21:49:55 2018 -0700
need these APIs
---
frameworks/js/projects/MXRoyaleJS/src/main/config/compile-js-config.xml | 2 ++
frameworks/projects/MXRoyale/src/main/config/compile-swf-config.xml | 1 +
2 files changed, 3 insertions(+)
diff --git a/frameworks/js/projects/MXRoyaleJS/src/main/config/compile-js-config.xml b/frameworks/js/projects/MXRoyaleJS/src/main/config/compile-js-config.xml
index f5afbfa..61c8ac2 100644
--- a/frameworks/js/projects/MXRoyaleJS/src/main/config/compile-js-config.xml
+++ b/frameworks/js/projects/MXRoyaleJS/src/main/config/compile-js-config.xml
@@ -69,6 +69,8 @@
<path-element>../../../../../libs/ExpressJS.swc</path-element>
<path-element>../../../../../libs/GraphicsJS.swc</path-element>
<path-element>../../../../../libs/ChartsJS.swc</path-element>
+ <path-element>../../../../../libs/ReflectionJS.swc</path-element>
+ <path-element>../../../../../libs/XMLJS.swc</path-element>
</library-path>
<namespaces>
diff --git a/frameworks/projects/MXRoyale/src/main/config/compile-swf-config.xml b/frameworks/projects/MXRoyale/src/main/config/compile-swf-config.xml
index 46220cb..f1ecd69 100644
--- a/frameworks/projects/MXRoyale/src/main/config/compile-swf-config.xml
+++ b/frameworks/projects/MXRoyale/src/main/config/compile-swf-config.xml
@@ -39,6 +39,7 @@
<path-element>../../../../../libs/Effects.swc</path-element>
<path-element>../../../../../libs/Express.swc</path-element>
<path-element>../../../../../libs/Charts.swc</path-element>
+ <path-element>../../../../../libs/Reflection.swc</path-element>
</external-library-path>
<allow-subclass-overrides>true</allow-subclass-overrides>
[royale-asjs] 07/09: typo
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aharui pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit 8a3f7d289a48560f7ee15b818a44b27f691b8017
Author: Alex Harui <ah...@apache.org>
AuthorDate: Wed Aug 8 10:42:14 2018 -0700
typo
---
frameworks/projects/MXRoyale/src/main/royale/mx/controls/TextArea.as | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/TextArea.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/TextArea.as
index 991954d..da10a66 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/TextArea.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/TextArea.as
@@ -87,7 +87,7 @@ use namespace mx_internal;
* @playerversion AIR 1.1
* @productversion Flex 3
*/
-[Event(name="change", type="org.apache.royale.evets.Event")]
+[Event(name="change", type="org.apache.royale.events.Event")]
/**
* Dispatched when the <code>data</code> property changes.
[royale-asjs] 02/09: get binding to work
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aharui pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit d4dcbb295adfbed1272fc7e0f2679b8d1d2a9676
Author: Alex Harui <ah...@apache.org>
AuthorDate: Mon Aug 6 16:55:53 2018 -0700
get binding to work
---
.../MXRoyale/src/main/royale/mx/core/Application.as | 13 ++++++++++---
.../projects/MXRoyale/src/main/royale/mx/core/Container.as | 7 ++++++-
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/Application.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/Application.as
index b9da637..aa6abc9 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/Application.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/Application.as
@@ -62,11 +62,12 @@ import flash.utils.getQualifiedClassName;
import org.apache.royale.events.utils.MouseEventConverter;
}
-import mx.managers.FocusManager;
import mx.containers.beads.ApplicationLayout;
import mx.containers.beads.BoxLayout;
+import mx.managers.FocusManager;
import org.apache.royale.binding.ApplicationDataBinding;
+import org.apache.royale.binding.ContainerDataBinding;
import org.apache.royale.core.AllCSSValuesImpl;
import org.apache.royale.core.IBead;
import org.apache.royale.core.IBeadLayout;
@@ -84,8 +85,8 @@ import org.apache.royale.events.Event;
import org.apache.royale.events.IEventDispatcher;
import org.apache.royale.events.ValueChangeEvent;
import org.apache.royale.states.State;
-import org.apache.royale.utils.MixinManager;
import org.apache.royale.utils.MXMLDataInterpreter;
+import org.apache.royale.utils.MixinManager;
import org.apache.royale.utils.Timer;
import org.apache.royale.utils.loadBeadFromValuesManager;
@@ -523,7 +524,13 @@ public class Application extends Container implements IStrand, IParent, IEventDi
// Initialization and Start-up
//
//--------------------------------------------------------------------------
-
+
+ override protected function createChildren():void
+ {
+ super.createChildren();
+ dispatchEvent(new org.apache.royale.events.Event("viewChanged"));
+ }
+
/**
* @private
*/
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/Container.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/Container.as
index c5db136..3932df4 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/Container.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/Container.as
@@ -19,6 +19,8 @@
package mx.core
{
+ import org.apache.royale.binding.DataBindingBase;
+ import org.apache.royale.binding.ContainerDataBinding;
import org.apache.royale.core.ContainerBaseStrandChildren;
import org.apache.royale.core.IBeadLayout;
import org.apache.royale.core.IBorderPaddingMarginValuesImpl
@@ -622,7 +624,10 @@ public class Container extends UIComponent
override protected function createChildren():void
{
MXMLDataInterpreter.generateMXMLInstances(_mxmlDocument, this, MXMLDescriptor);
-
+
+ if (getBeadByType(DataBindingBase) == null)
+ addBead(new ContainerDataBinding());
+
dispatchEvent(new Event("initBindings"));
dispatchEvent(new Event("initComplete"));
}
[royale-asjs] 06/09: tune up fonts to be more like Flex
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aharui pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit f0dac13208f38e52c2cf83365bdfeec511d7faeb
Author: Alex Harui <ah...@apache.org>
AuthorDate: Tue Aug 7 21:50:50 2018 -0700
tune up fonts to be more like Flex
---
frameworks/projects/MXRoyale/src/main/resources/defaults.css | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/frameworks/projects/MXRoyale/src/main/resources/defaults.css b/frameworks/projects/MXRoyale/src/main/resources/defaults.css
index 1e189c4..af62244 100644
--- a/frameworks/projects/MXRoyale/src/main/resources/defaults.css
+++ b/frameworks/projects/MXRoyale/src/main/resources/defaults.css
@@ -25,6 +25,11 @@
box-sizing: border-box;
}
+* {
+ font-family: Verdana;
+ font-size: 12px;
+}
+
global {
IStatesImpl: ClassReference("org.apache.royale.core.StatesWithTransitionsImpl");
IEffectTimer: ClassReference("org.apache.royale.utils.EffectTimer");
@@ -211,6 +216,10 @@ Panel .TitleBar
background-color: #FFFFFF;
}
+Basic|TitleBar
+{
+ font-weight: bold;
+}
/* -------------------------------------------------------
* SWF specific styles
[royale-asjs] 01/09: handle initial sizing
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aharui pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit dc531d7e61eaa1d7d43dd452ec29f58bb10008a5
Author: Alex Harui <ah...@apache.org>
AuthorDate: Mon Aug 6 16:41:53 2018 -0700
handle initial sizing
---
.../src/main/royale/mx/managers/SystemManager.as | 24 +++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/managers/SystemManager.as b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/SystemManager.as
index f06a06a..dfc2d2a 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/managers/SystemManager.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/SystemManager.as
@@ -91,12 +91,14 @@ import mx.utils.LoaderUtil;
use namespace mx_internal;
*/
+import org.apache.royale.geom.Rectangle;
+
import mx.core.IChildList;
import mx.core.IFlexDisplayObject;
import mx.core.IUIComponent;
import org.apache.royale.core.IUIBase;
-import org.apache.royale.events.IEventDispatcher;
+import org.apache.royale.events.IEventDispatcher;
//--------------------------------------
// Events
@@ -1327,8 +1329,9 @@ public class SystemManager extends SystemManagerBase implements ISystemManager,
* @playerversion AIR 1.1
* @productversion Royale 0.9.4
*/
- /* public function get screen():Rectangle
+ public function get screen():Rectangle
{
+ /* Flex code (why so complicated?)
if (!_screen)
Stage_resizeHandler();
@@ -1337,7 +1340,16 @@ public class SystemManager extends SystemManagerBase implements ISystemManager,
Stage_resizeHandler();
}
return _screen;
- } */
+ */
+ COMPILE::SWF
+ {
+ return new Rectangle(0, 0, stage.width, stage.height);
+ }
+ COMPILE::JS
+ {
+ return new Rectangle(0, 0, window.innerWidth, window.innerHeight);
+ }
+ }
//----------------------------------
// toolTipChildren
@@ -2903,10 +2915,8 @@ public class SystemManager extends SystemManagerBase implements ISystemManager,
// until preloader?
component.addEventListener("applicationComplete", applicationCompleteHandler);
addChild(component as IUIComponent);
- COMPILE::SWF
- {
- component.setActualSize(stage.stageWidth, stage.stageHeight);
- }
+ var screen:Rectangle = this.screen;
+ component.setActualSize(screen.width, screen.height);
}
private function applicationCompleteHandler(event:Event):void
[royale-asjs] 08/09: can't use braces here
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aharui pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit 48f077005cdfe0ef9d7e740a26063038aca254d9
Author: Alex Harui <ah...@apache.org>
AuthorDate: Wed Aug 8 10:42:38 2018 -0700
can't use braces here
---
frameworks/projects/MXRoyale/src/main/royale/mx/errors/EOFError.as | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/errors/EOFError.as b/frameworks/projects/MXRoyale/src/main/royale/mx/errors/EOFError.as
index 0d1b7cf..964894a 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/errors/EOFError.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/errors/EOFError.as
@@ -32,7 +32,7 @@ import flash.errors.EOFError;
*
* @royalesuppresspublicvarwarning
*/
- COMPILE::SWF{
+COMPILE::SWF
public class EOFError extends flash.errors.EOFError
{
//--------------------------------------------------------------------------
@@ -56,8 +56,8 @@ public class EOFError extends flash.errors.EOFError
}
-}
-COMPILE::JS{
+
+COMPILE::JS
public class EOFError extends Object
{
//--------------------------------------------------------------------------
@@ -81,6 +81,5 @@ public class EOFError extends Object
}
-}
}
[royale-asjs] 03/09: manually copy data file
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aharui pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit eaff36ca58fbedea42cb095aaf56e52edbcf3d78
Author: Alex Harui <ah...@apache.org>
AuthorDate: Mon Aug 6 16:59:21 2018 -0700
manually copy data file
---
examples/mxroyale/tourdeflexmodules/build.xml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/examples/mxroyale/tourdeflexmodules/build.xml b/examples/mxroyale/tourdeflexmodules/build.xml
index 02d7f48..dc719a7 100644
--- a/examples/mxroyale/tourdeflexmodules/build.xml
+++ b/examples/mxroyale/tourdeflexmodules/build.xml
@@ -122,6 +122,8 @@
<compile-mxml example="/SourceTab"/>
-->
<compile-mxml example="/Welcome"/>
+ <copy file="${basedir}/src/3rdparty.xml" toFile="${basedir}/bin/js-debug/3rdparty.xml" />
+ <!--<copy file="${basedir}/src/3rdparty.xml" toFile="${basedir}/bin/js-release/3rdparty.xml" />-->
</target>
<target name="compile-mx" description="compile mx examples">
[royale-asjs] 04/09: fix folder name
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aharui pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit 05388841af3c9014582b00510d46206b9b385395
Author: Alex Harui <ah...@apache.org>
AuthorDate: Tue Aug 7 21:48:53 2018 -0700
fix folder name
---
.../src/main/royale/mx/collections/{error => errors}/SortError.as | 0
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/error/SortError.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/errors/SortError.as
similarity index 100%
rename from frameworks/projects/MXRoyale/src/main/royale/mx/collections/error/SortError.as
rename to frameworks/projects/MXRoyale/src/main/royale/mx/collections/errors/SortError.as
[royale-asjs] 09/09: see how much of Flex collections we can reuse.
This compiles but will it run?
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aharui pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit 166b8ca4b89e063949db41d8abe7504cc2593890
Author: Alex Harui <ah...@apache.org>
AuthorDate: Wed Aug 8 17:22:56 2018 -0700
see how much of Flex collections we can reuse. This compiles but will it run?
---
.../MXRoyale/src/main/resources/defaults.css | 8 +
.../MXRoyale/src/main/royale/MXRoyaleClasses.as | 3 +
.../main/royale/mx/collections/ArrayCollection.as | 6 +-
.../main/royale/mx/collections/ICollectionView.as | 7 +-
.../src/main/royale/mx/collections/ISort.as | 34 +-
.../src/main/royale/mx/collections/ISortField.as | 544 +--
.../royale/mx/collections/ListCollectionView.as | 3528 ++++++++++++++++----
.../src/main/royale/mx/collections/Sort.as | 1052 ++++--
.../src/main/royale/mx/collections/SortField.as | 1703 +++++-----
.../royale/mx/collections/SortFieldCompareTypes.as | 117 +
.../main/royale/mx/collections/XMLListAdapter.as | 826 +++++
.../royale/mx/collections/XMLListCollection.as | 400 ++-
.../CursorError.as} | 54 +-
.../MXRoyale/src/main/royale/mx/controls/Tree.as | 58 +-
.../models/SingleSelectionICollectionViewModel.as | 271 ++
.../beads/models/SingleSelectionIListModel.as | 247 ++
.../royale/mx/controls/listClasses/ListBase.as | 49 +-
.../controls/treeClasses/DefaultDataDescriptor.as | 779 +++++
.../treeClasses/HierarchicalCollectionView.as | 1125 +++++++
.../controls/treeClasses/HierarchicalViewCursor.as | 982 ++++++
.../mx/controls/treeClasses/ITreeDataDescriptor.as | 76 +
.../controls/treeClasses/ITreeDataDescriptor2.as | 107 +
.../main/royale/mx/core/IPropertyChangeNotifier.as | 97 +
.../MXRoyale/src/main/royale/mx/core/IUID.as | 62 +
.../src/main/royale/mx/utils/IXMLNotifiable.as | 43 +
.../MXRoyale/src/main/royale/mx/utils/UIDUtil.as | 298 ++
.../src/main/royale/mx/utils/XMLNotifier.as | 276 ++
27 files changed, 10632 insertions(+), 2120 deletions(-)
diff --git a/frameworks/projects/MXRoyale/src/main/resources/defaults.css b/frameworks/projects/MXRoyale/src/main/resources/defaults.css
index af62244..1290db4 100644
--- a/frameworks/projects/MXRoyale/src/main/resources/defaults.css
+++ b/frameworks/projects/MXRoyale/src/main/resources/defaults.css
@@ -221,6 +221,14 @@ Basic|TitleBar
font-weight: bold;
}
+Tree
+{
+ IBeadModel: ClassReference("mx.controls.beads.models.SingleSelectionICollectionViewModel");
+ IBeadController: ClassReference("org.apache.royale.html.beads.controllers.TreeSingleSelectionMouseController");
+ IDataProviderItemRendererMapper: ClassReference("org.apache.royale.html.beads.DataItemRendererFactoryForHierarchicalData");
+ IItemRenderer: ClassReference("org.apache.royale.html.supportClasses.TreeItemRenderer");
+}
+
/* -------------------------------------------------------
* SWF specific styles
* -------------------------------------------------------
diff --git a/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as b/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
index 985f931..388d51f 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
@@ -156,6 +156,9 @@ internal class MXRoyaleClasses
import mx.containers.beads.PanelView; PanelView;
import mx.containers.beads.models.PanelModel; PanelModel;
+
+ import mx.controls.beads.models.SingleSelectionICollectionViewModel; SingleSelectionICollectionViewModel;
+ import mx.controls.beads.models.SingleSelectionIListModel; SingleSelectionIListModel;
}
}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayCollection.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayCollection.as
index 2acebf9..d0a7bba 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayCollection.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayCollection.as
@@ -131,10 +131,10 @@ public class ArrayCollection extends ListCollectionView //implements IExternaliz
*/
public function get source():Array
{
- /*if (list && (list is ArrayList))
+ if (list && (list is ArrayList))
{
return ArrayList(list).source;
- }*/
+ }
return null;
}
@@ -143,7 +143,7 @@ public class ArrayCollection extends ListCollectionView //implements IExternaliz
*/
public function set source(s:Array):void
{
- //list = new ArrayList(s);
+ list = new ArrayList(s);
}
}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ICollectionView.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ICollectionView.as
index 0013674..2940a81 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ICollectionView.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ICollectionView.as
@@ -19,11 +19,10 @@
package mx.collections
{
+import mx.events.CollectionEvent;
-/* import flash.events.IEventDispatcher;
- */
- import org.apache.royale.events.IEventDispatcher;
- import mx.events.CollectionEvent;
+import org.apache.royale.collections.ICollectionView;
+import org.apache.royale.events.IEventDispatcher;
/**
* Dispatched when the ICollectionView has been updated in some way.
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ISort.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ISort.as
index ed8b5cd..640b49a 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ISort.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ISort.as
@@ -31,7 +31,7 @@ package mx.collections
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
- * @productversion Royale 0.9.4
+ * @productversion Flex 4.5
*/
public interface ISort
{
@@ -125,15 +125,15 @@ public interface ISort
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
- * @productversion Royale 0.9.4
+ * @productversion Flex 4.5
*/
- //function get compareFunction():Function;
+ function get compareFunction():Function;
/**
* @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
* argument instead.
*/
- //function set compareFunction(value:Function):void;
+ function set compareFunction(value:Function):void;
/**
* An <code>Array</code> of <code>ISortField</code> objects that
@@ -151,7 +151,7 @@ public interface ISort
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
- * @productversion Royale 0.9.4
+ * @productversion Flex 4.5
*/
function get fields():Array;
@@ -177,15 +177,15 @@ public interface ISort
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
- * @productversion Royale 0.9.4
+ * @productversion Flex 4.5
*/
- // function get unique():Boolean;
+ function get unique():Boolean;
/**
* @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
* argument instead.
*/
- // function set unique(value:Boolean):void;
+ function set unique(value:Boolean):void;
//--------------------------------------------------------------------------
//
@@ -282,14 +282,14 @@ public interface ISort
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
- * @productversion Royale 0.9.4
+ * @productversion Flex 4.5
*/
- /* function findItem(
+ function findItem(
items:Array,
values:Object,
mode:String,
returnInsertionIndex:Boolean = false,
- compareFunction:Function = null):int; */
+ compareFunction:Function = null):int;
/**
* Return whether the specified property is used to control the sort.
@@ -307,9 +307,9 @@ public interface ISort
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
- * @productversion Royale 0.9.4
+ * @productversion Flex 4.5
*/
- /* function propertyAffectsSort(property:String):Boolean; */
+ function propertyAffectsSort(property:String):Boolean;
/**
* Goes through the <code>fields</code> array and calls
@@ -328,9 +328,9 @@ public interface ISort
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
- * @productversion Royale 0.9.4
+ * @productversion Flex 4.5
*/
- /* function reverse():void; */
+ function reverse():void;
/**
* Apply the current sort to the specified array (not a copy).
@@ -346,8 +346,8 @@ public interface ISort
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
- * @productversion Royale 0.9.4
+ * @productversion Flex 4.5
*/
- /* function sort(items:Array):void; */
+ function sort(items:Array):void;
}
}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ISortField.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ISortField.as
index bd51697..766bd69 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ISortField.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ISortField.as
@@ -1,272 +1,272 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-package mx.collections
-{
-/**
- * The <code>ISortField</code> interface defines the interface for classes that
- * are used with <code>ISort</code> classes, to provide the sorting information
- * required to sort the specific fields or property in a collection view.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
-public interface ISortField
- {
- //--------------------------------------------------------------------------
- //
- // Properties
- //
- //--------------------------------------------------------------------------
-
- /**
- * This helper property is used internally by the <code>findItem()</code>
- * and <code>sort()</code> methods. Other uses of this property are not
- * supported.
- * Returns -1 if this ISortField shouldn't be used by the <code>Sort</code>
- * class to sort the field (there is no compareFunction or no name). Otherwise, returns a bitmask of sort options.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- // function get arraySortOnOptions():int;
-
- /**
- * The function that compares two items during a sort of items for the
- * associated collection. If you specify a <code>compareFunction</code>
- * property in an ISort object, Flex ignores any
- * <code>compareFunction</code> properties of the ISort's ISortField
- * objects.
- * <p>The compare function must have the following signature:</p>
- *
- * <p><code>function myCompare(a:Object, b:Object):int</code></p>
- *
- * <p>This function returns the following values:</p>
- *
- * <ul>
- * <li>-1, if <code>a</code> should appear before <code>b</code> in
- * the sorted sequence</li>
- * <li>0, if <code>a</code> equals <code>b</code></li>
- * <li>1, if <code>a</code> should appear after <code>b</code> in the
- * sorted sequence</li>
- * </ul>
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- // function get compareFunction():Function;
-
- /**
- * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
- * argument instead.
- */
- // function set compareFunction(c:Function):void;
-
- /**
- * Specifies whether this field should be sorted in descending
- * order.
- *
- * <p>The default value is <code>false</code> (ascending).</p>
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- // function get descending():Boolean;
-
- /**
- * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
- * argument instead.
- */
- // function set descending(value:Boolean):void;
-
- /**
- * The name of the field to be sorted.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- function get name():String;
-
- /**
- * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
- * argument instead.
- */
- function set name(n:String):void;
-
- /**
- * Specifies that if the field being sorted contains numeric
- * (<code>number/int/uint</code>) values, or string representations of numeric values,
- * the comparator use a numeric comparison.
- * <p>
- * This property is used by <code>SortField</code> class in case custom compare
- * function is not provided.
- * </p>
- * <p>
- * If this property is <code>true</code>, the built-in numeric compare
- * function is used. Each of data items is cast to a
- * <code>Number()</code> function before the comparison.
- * </p>
- * <p>
- * If this property is <code>false</code>, the built-in string compare
- * function is used. Each of data items is cast to a
- * <code>String()</code> function before the comparison.
- * </p>
- * <p>
- * If this property is <code>null</code>, the first data item
- * is introspected to see if it is a number or string and the sort
- * proceeds based on that introspection.
- * </p>
- *
- * @default null
- *
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- function get numeric():Object;
-
- /**
- * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
- * argument instead.
- */
- function set numeric(value:Object):void;
-
-
- /**
- * Specifies what compare type will be used for the sortField. This overrides the default
- * behavior.
- *
- * @default null
- *
- * @langversion 3.0
- * @playerversion Flash 11.8
- * @playerversion AIR 3.8
- * @productversion Royale 0.9.4
- */
- // function get sortCompareType():String;
-
- /**
- * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
- * argument instead.
- */
- // function set sortCompareType(value:String):void;
-
-
- /**
- * True if this <code>ISortField</code> uses a custom comparator function.
- *
- * @see @compareFunction
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- // function get usingCustomCompareFunction():Boolean;
-
- //--------------------------------------------------------------------------
- //
- // Methods
- //
- //--------------------------------------------------------------------------
-
- /**
- * A helper function called by the <code>Sort</code> class to set the
- * default comparison function to perform a comparison based on
- * one of three things: whether or not a custom compare function has
- * been set, the data type for the specified field or the the value of the
- * numeric property. If the the <code>numeric</code> property is true,
- * then a numeric comparison will be performed when sorting.
- *
- * @param obj The object that contains the data. If the field name has
- * been set with the name property, then the name will be used to access
- * the data value from this object. Otherwise the object itself will
- * be used as the data value.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- // function initializeDefaultCompareFunction(obj:Object):void;
-
- /**
- * Reverse the criteria for this sort field.
- * If the field was sorted in descending order, for example, sort it
- * in ascending order.
- *
- * <p>NOTE: An <code>ICollectionView</code> does not automatically
- * update when the <code>ISortFields</code> are modified; call its
- * <code>refresh()</code> method to update the view.</p>
- *
- * <p>Note: a future release of Apache Flex SDK will change the signature
- * of this function to return a reversed clone of this SortField instance.
- * See FLEX-34853 for more details.</p>
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- // function reverse():void;
-
-
- /**
- * This changes the internal compare function used by the <code>SortField</code> based
- * on the value of <code>sortCompareType</code>.
- *
- * @deprecated A future release of Apache Flex SDK will remove this function in favour of
- * making ISortField instances immutable.
- *
- * @return true for successfully matched or false for failure to match the <code>sortCompareType</code>.
- *
- * @langversion 3.0
- * @playerversion Flash 11.8
- * @playerversion AIR 3.8
- * @productversion Royale 0.9.4
- */
- // function updateSortCompareType():Boolean;
-
- /**
- * Returns true if the object has the field required by this <code>ISortField</code> instance.
- * In the case of <code>ComplexSortField</code>, returns true if the object has a field with
- * an identical name to the first part of the <code>namePath</code>.
- *
- * @return true if the object has the field required by this <code>ISortField</code> instance.
- *
- * @langversion 3.0
- * @playerversion Flash 11.8
- * @playerversion AIR 3.8
- * @productversion Royale 0.9.4
- */
- // function objectHasSortField(object:Object):Boolean;
-}
-}
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.collections
+{
+/**
+ * The <code>ISortField</code> interface defines the interface for classes that
+ * are used with <code>ISort</code> classes, to provide the sorting information
+ * required to sort the specific fields or property in a collection view.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 4.5
+ */
+public interface ISortField
+ {
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * This helper property is used internally by the <code>findItem()</code>
+ * and <code>sort()</code> methods. Other uses of this property are not
+ * supported.
+ * Returns -1 if this ISortField shouldn't be used by the <code>Sort</code>
+ * class to sort the field (there is no compareFunction or no name). Otherwise, returns a bitmask of sort options.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 4.5
+ */
+ function get arraySortOnOptions():int;
+
+ /**
+ * The function that compares two items during a sort of items for the
+ * associated collection. If you specify a <code>compareFunction</code>
+ * property in an ISort object, Flex ignores any
+ * <code>compareFunction</code> properties of the ISort's ISortField
+ * objects.
+ * <p>The compare function must have the following signature:</p>
+ *
+ * <p><code>function myCompare(a:Object, b:Object):int</code></p>
+ *
+ * <p>This function returns the following values:</p>
+ *
+ * <ul>
+ * <li>-1, if <code>a</code> should appear before <code>b</code> in
+ * the sorted sequence</li>
+ * <li>0, if <code>a</code> equals <code>b</code></li>
+ * <li>1, if <code>a</code> should appear after <code>b</code> in the
+ * sorted sequence</li>
+ * </ul>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 4.5
+ */
+ function get compareFunction():Function;
+
+ /**
+ * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
+ * argument instead.
+ */
+ function set compareFunction(c:Function):void;
+
+ /**
+ * Specifies whether this field should be sorted in descending
+ * order.
+ *
+ * <p>The default value is <code>false</code> (ascending).</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 4.5
+ */
+ function get descending():Boolean;
+
+ /**
+ * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
+ * argument instead.
+ */
+ function set descending(value:Boolean):void;
+
+ /**
+ * The name of the field to be sorted.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 4.5
+ */
+ function get name():String;
+
+ /**
+ * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
+ * argument instead.
+ */
+ function set name(n:String):void;
+
+ /**
+ * Specifies that if the field being sorted contains numeric
+ * (<code>number/int/uint</code>) values, or string representations of numeric values,
+ * the comparator use a numeric comparison.
+ * <p>
+ * This property is used by <code>SortField</code> class in case custom compare
+ * function is not provided.
+ * </p>
+ * <p>
+ * If this property is <code>true</code>, the built-in numeric compare
+ * function is used. Each of data items is cast to a
+ * <code>Number()</code> function before the comparison.
+ * </p>
+ * <p>
+ * If this property is <code>false</code>, the built-in string compare
+ * function is used. Each of data items is cast to a
+ * <code>String()</code> function before the comparison.
+ * </p>
+ * <p>
+ * If this property is <code>null</code>, the first data item
+ * is introspected to see if it is a number or string and the sort
+ * proceeds based on that introspection.
+ * </p>
+ *
+ * @default null
+ *
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 4.5
+ */
+ function get numeric():Object;
+
+ /**
+ * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
+ * argument instead.
+ */
+ function set numeric(value:Object):void;
+
+
+ /**
+ * Specifies what compare type will be used for the sortField. This overrides the default
+ * behavior.
+ *
+ * @default null
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11.8
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.11
+ */
+ function get sortCompareType():String;
+
+ /**
+ * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
+ * argument instead.
+ */
+ function set sortCompareType(value:String):void;
+
+
+ /**
+ * True if this <code>ISortField</code> uses a custom comparator function.
+ *
+ * @see @compareFunction
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 4.5
+ */
+ function get usingCustomCompareFunction():Boolean;
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * A helper function called by the <code>Sort</code> class to set the
+ * default comparison function to perform a comparison based on
+ * one of three things: whether or not a custom compare function has
+ * been set, the data type for the specified field or the the value of the
+ * numeric property. If the the <code>numeric</code> property is true,
+ * then a numeric comparison will be performed when sorting.
+ *
+ * @param obj The object that contains the data. If the field name has
+ * been set with the name property, then the name will be used to access
+ * the data value from this object. Otherwise the object itself will
+ * be used as the data value.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 4.5
+ */
+ function initializeDefaultCompareFunction(obj:Object):void;
+
+ /**
+ * Reverse the criteria for this sort field.
+ * If the field was sorted in descending order, for example, sort it
+ * in ascending order.
+ *
+ * <p>NOTE: An <code>ICollectionView</code> does not automatically
+ * update when the <code>ISortFields</code> are modified; call its
+ * <code>refresh()</code> method to update the view.</p>
+ *
+ * <p>Note: a future release of Apache Flex SDK will change the signature
+ * of this function to return a reversed clone of this SortField instance.
+ * See FLEX-34853 for more details.</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 4.5
+ */
+ function reverse():void;
+
+
+ /**
+ * This changes the internal compare function used by the <code>SortField</code> based
+ * on the value of <code>sortCompareType</code>.
+ *
+ * @deprecated A future release of Apache Flex SDK will remove this function in favour of
+ * making ISortField instances immutable.
+ *
+ * @return true for successfully matched or false for failure to match the <code>sortCompareType</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11.8
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.11
+ */
+ function updateSortCompareType():Boolean;
+
+ /**
+ * Returns true if the object has the field required by this <code>ISortField</code> instance.
+ * In the case of <code>ComplexSortField</code>, returns true if the object has a field with
+ * an identical name to the first part of the <code>namePath</code>.
+ *
+ * @return true if the object has the field required by this <code>ISortField</code> instance.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11.8
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.15
+ */
+ function objectHasSortField(object:Object):Boolean;
+}
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ListCollectionView.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ListCollectionView.as
index 0b12b50..0452d98 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ListCollectionView.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ListCollectionView.as
@@ -1,668 +1,2862 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-package mx.collections
-{
- COMPILE::JS {
- import goog.DEBUG;
- }
- import org.apache.royale.events.Event;
- import org.apache.royale.events.EventDispatcher
- /*
- import flash.events.Event;
- import flash.events.EventDispatcher;
- import flash.utils.Proxy;
- import flash.utils.flash_proxy;
- import flash.utils.getQualifiedClassName;
-
- import mx.binding.utils.BindingUtils;
- import mx.binding.utils.ChangeWatcher;
- import mx.collections.errors.CollectionViewError;
- import mx.collections.errors.ItemPendingError;
- import mx.collections.errors.SortError;
- import mx.core.IMXMLObject;
- import mx.core.mx_internal;
- import mx.events.CollectionEvent;
- import mx.events.CollectionEventKind;
- import mx.events.PropertyChangeEvent;
- import mx.resources.IResourceManager;
- import mx.resources.ResourceManager;
- import mx.utils.ObjectUtil;
-
- use namespace mx_internal;
- */
-
-/**
- * Dispatched when the ICollectionView has been updated in some way.
- *
- * @eventType mx.events.CollectionEvent.COLLECTION_CHANGE
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
-[Event(name="collectionChange", type="mx.events.CollectionEvent")]
-
-//[ResourceBundle("collections")]
-
-/**
- * The ListCollectionView class adds the properties and methods of the
- * <code>ICollectionView</code> interface to an object that conforms to the
- * <code>IList</code> interface. As a result, you can pass an object of this class
- * to anything that requires an <code>IList</code> or <code>ICollectionView</code>.
- *
- * <p>This class also lets you use [ ] array notation
- * to access the <code>getItemAt()</code> and <code>setItemAt()</code> methods.
- * If you use code such as <code>myListCollectionView[index]</code>
- * Flex calls the <code>myListCollectionView</code> object's
- * <code>getItemAt()</code> or <code>setItemAt()</code> method.</p>
- *
- * @mxml
- *
- * <p>The <code><mx:ListCollectionView></code> has the following attributes,
- * which all of its subclasses inherit:</p>
- *
- * <pre>
- * <mx:ListCollectionView
- * <b>Properties</b>
- * filterFunction="null"
- * list="null"
- * sort="null"
- * <b>Events</b>
- * collectionChange="<i>No default</i>"
- * />
- * </pre>
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
-public class ListCollectionView //extends Proxy implements ICollectionView, IList, IMXMLObject
-{
- //include "../core/Version.as";
-
- //--------------------------------------------------------------------------
- //
- // Private variables
- //
- //--------------------------------------------------------------------------
-
- /**
- * @private
- * Change watcher for complex sort fields.
- */
- //private var _complexFieldWatcher:ComplexFieldChangeWatcher;
-
- /**
- * @private
- * Internal event dispatcher.
- */
- private var eventDispatcher:EventDispatcher;
-
- //mx_internal var dispatchResetEvent:Boolean = true;
-
- /**
- * @private
- * Used for accessing localized Error messages.
- */
- /*
- private var resourceManager:IResourceManager =
- ResourceManager.getInstance();
- */
- //--------------------------------------------------------------------------
- //
- // Protected variables
- //
- //--------------------------------------------------------------------------
-
- /**
- * When the view is sorted or filtered the <code>localIndex</code> property
- * contains an array of items in the sorted or filtered (ordered, reduced)
- * view, in the sorted order.
- * The ListCollectionView class uses this property to access the items in
- * the view.
- * The <code>localIndex</code> property should never contain anything
- * that is not in the source, but may not have everything in the source.
- * This property is <code>null</code> when there is no sort.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- protected var localIndex:Array;
-
- //--------------------------------------------------------------------------
- //
- // Constructor
- //
- //--------------------------------------------------------------------------
-
- /**
- * The ListCollectionView constructor.
- *
- * @param list the IList this ListCollectionView is meant to wrap.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function ListCollectionView(list:IList = null)
- {
- super();
-
- //eventDispatcher = new EventDispatcher(this);
- //this.list = list;
- }
-
- /**
- * Adds a list of items to the current list, placing them at the end of
- * the list in the order they are passed.
- *
- * @param addList IList The list of items to add to the current list
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function addAll(addList:IList):void
- {
- if (localIndex)
- addAllAt(addList, localIndex.length);
- else
- addAllAt(addList, length);
- }
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function addItem(item:Object):void
- {
- if (localIndex)
- addItemAt(item, localIndex.length);
- else
- addItemAt(item, length);
- }
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function addItemAt(item:Object, index:int):void
- {
- /*
- if (index < 0 || !list || index > length)
- {
- var message:String = resourceManager.getString(
- "collections", "outOfBounds", [ index ]);
-
- throw new RangeError(message);
- }
-
- var listIndex:int = index;
-
- // if we're sorted addItemAt is meaningless, just add to the end
- if (localIndex && sort)
- {
- listIndex = list.length;
- }
- else if (localIndex && filterFunction != null)
- {
- // if end of filtered list, put at end of source list
- if (listIndex == localIndex.length)
- listIndex = list.length;
- // if somewhere in filtered list, find it and insert before it
- // or at beginning
- else
- listIndex = list.getItemIndex(localIndex[index]);
- }
- // List is sorted or filtered but refresh has not been called
- // Just add to end of list
- else if (localIndex)
- {
- listIndex = list.length;
- }
-
- list.addItemAt(item, listIndex);
- */
- }
-
- /**
- * Adds a list of items to the current list, placing them at the position
- * index passed in to the function. The items are placed at the index location
- * and placed in the order they are recieved.
- *
- * @param addList IList The list of items to add to the current list
- * @param index The location of the current list to place the new items.
- * @throws RangeError if index is less than 0 or greater than the length of the list.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function addAllAt(addList:Object, index:int):void
- //(addList:IList, index:int):void
- {
- /*if (index < 0 || index > this.length)
- {
- var message:String = resourceManager.getString(
- "collections", "outOfBounds", [ index ]);
- throw new RangeError(message);
- }
-
- var length:int = addList.length;
-
- for (var i:int=0; i < length; i++)
- {
- var insertIndex:int = i + index;
-
- // incremental index may be out of bounds because of filtering,
- // so add this item to the end.
- if (insertIndex > this.length)
- insertIndex = this.length;
-
- this.addItemAt(addList.getItemAt(i), insertIndex);
- }*/
- }
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function getItemAt(index:int, prefetch:int = 0):Object
- {
- /*
- if (index < 0 || index >= length)
- {
- var message:String = resourceManager.getString(
- "collections", "outOfBounds", [ index ]);
-
- throw new RangeError(message);
- }
-
- if (localIndex)
- {
- return localIndex[index];
- }
- else if (list)
- {
- return list.getItemAt(index, prefetch);
- }
- */
- return null;
- }
-
- //----------------------------------
- // length
- //----------------------------------
-
- [Bindable("collectionChange")]
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function get length():int
- {
- if (localIndex)
- {
- return localIndex.length;
- }
- /*else if (list)
- {
- return list.length;
- }*/
- else
- {
- return 0;
- }
- }
-
- //----------------------------------
- // list
- //----------------------------------
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function refresh():Boolean
- {
- return true; //internalRefresh(true);
- }
-
- /**
- * Remove all items from the list.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function removeAll():void
- {
- /*
- var len:int = length;
- if (len > 0)
- {
- if (localIndex && filterFunction != null)
- {
- len = localIndex.length;
- for (var i:int = len - 1; i >= 0; i--)
- {
- removeItemAt(i);
- }
- }
- else
- {
- localIndex = null;
- list.removeAll();
- }
- }
- */
- }
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function removeItemAt(index:int):Object
- {
- /*
- if (index < 0 || index >= length)
- {
- var message:String = resourceManager.getString(
- "collections", "outOfBounds", [ index ]);
- throw new RangeError(message);
- }
-
- var listIndex:int = index;
- if (localIndex)
- {
- var oldItem:Object = localIndex[index];
- listIndex = list.getItemIndex(oldItem);
- }
- return list.removeItemAt(listIndex);
- */
- return null;
- }
-
- //----------------------------------
- // sort
- //----------------------------------
-
- /**
- * @private
- * Storage for the sort property.
- */
- private var _sort:ISort;
-
- [Bindable("sortChanged")]
- [Inspectable(category="General")]
-
- /**
- * @inheritDoc
- *
- * @see #refresh()
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function get sort():ISort
- {
- return _sort;
- }
-
- /**
- * @private
- */
- public function set sort(value:ISort):void
- {
- if(_sort != value)
- {
- //stopWatchingForComplexFieldsChanges();
-
- _sort = value;
-
- //startWatchingForComplexFieldsChanges();
-
- //dispatchEvent(new Event("sortChanged"));
- }
- }
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function toArray():Array
- {
- var ret:Array;
- if (localIndex)
- ret = localIndex.concat();
- /*
- else
- ret = list.toArray();
- */
- return ret;
- }
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function createCursor():void
- //IViewCursor
- {
- //return new ListCollectionViewCursor(this);
- }
-
- //----------------------------------
- // filterFunction
- //----------------------------------
-
- /**
- * @private
- * Storage for the filterFunction property.
- */
- private var _filterFunction:Function;
-
- [Bindable("filterFunctionChanged")]
- [Inspectable(category="General")]
-
- /**
- * @inheritDoc
- *
- * @see #refresh()
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function get filterFunction():Function
- {
- return _filterFunction;
- }
-
- /**
- * @private
- */
- public function set filterFunction(f:Function):void
- {
- /*
- _filterFunction = f;
- dispatchEvent(new Event("filterFunctionChanged"));
- */
- }
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function getItemIndex(item:Object):int
- {
- var i:int;
- /*
- if (localIndex && filterFunction != null)
- {
- var len:int = localIndex.length;
- for (i = 0; i < len; i++)
- {
- if (localIndex[i] == item)
- return i;
- }
-
- return -1;
- }
- else if (localIndex && sort)
- {
- var startIndex:int = findItem(item, Sort.FIRST_INDEX_MODE);
- if (startIndex == -1)
- return -1;
-
- var endIndex:int = findItem(item, Sort.LAST_INDEX_MODE);
- for (i = startIndex; i <= endIndex; i++)
- {
- if (localIndex[i] == item)
- return i;
- }
-
- return -1;
- }
- // List is sorted or filtered but refresh has not been called
- else if (localIndex)
- {
- len = localIndex.length;
- for (i = 0; i < len; i++)
- {
- if (localIndex[i] == item)
- return i;
- }
-
- return -1;
- }
-
- // fallback
- return list.getItemIndex(item);
- */
- return i;
- }
-
- /**
- * @inheritDoc
- *
- * @see mx.events.CollectionEvent
- * @see mx.core.IPropertyChangeNotifier
- * @see mx.events.PropertyChangeEvent
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function itemUpdated(item:Object, property:Object = null,
- oldValue:Object = null,
- newValue:Object = null):void
- {
- //list.itemUpdated(item, property, oldValue, newValue);
- }
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Flex 3
- */
- public function setItemAt(item:Object, index:int):Object
- {
- /*
- if (index < 0 || !list || index >= length)
- {
- var message:String = resourceManager.getString(
- "collections", "outOfBounds", [ index ]);
- throw new RangeError(message);
- }
-
- var listIndex:int = index;
- if (localIndex)
- {
- if (index > localIndex.length)
- {
- listIndex = list.length;
- }
- else
- {
- var oldItem:Object = localIndex[index];
- // FIXME fails on duplicates
- listIndex = list.getItemIndex(oldItem);
- }
- }
- return list.setItemAt(item, listIndex);
- */
- return null;
- }
-
- }
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.collections
+{
+
+ import org.apache.royale.events.Event;
+ import org.apache.royale.events.EventDispatcher;
+ import org.apache.royale.reflection.getQualifiedClassName;
+ import org.apache.royale.utils.Proxy;
+
+ COMPILE::SWF
+ {
+ import flash.utils.flash_proxy;
+ }
+
+ //import mx.binding.utils.ChangeWatcher;
+ //import mx.collections.errors.CollectionViewError;
+ //import mx.collections.errors.ItemPendingError;
+ import mx.collections.errors.SortError;
+ //import mx.core.IMXMLObject;
+ import mx.core.mx_internal;
+ import mx.events.CollectionEvent;
+ import mx.events.CollectionEventKind;
+ import mx.events.PropertyChangeEvent;
+ //import mx.resources.IResourceManager;
+ //import mx.resources.ResourceManager;
+ //import mx.utils.ObjectUtil;
+
+ use namespace mx_internal;
+
+/**
+ * Dispatched when the ICollectionView has been updated in some way.
+ *
+ * @eventType mx.events.CollectionEvent.COLLECTION_CHANGE
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+[Event(name="collectionChange", type="mx.events.CollectionEvent")]
+
+//[ResourceBundle("collections")]
+
+/**
+ * The ListCollectionView class adds the properties and methods of the
+ * <code>ICollectionView</code> interface to an object that conforms to the
+ * <code>IList</code> interface. As a result, you can pass an object of this class
+ * to anything that requires an <code>IList</code> or <code>ICollectionView</code>.
+ *
+ * <p>This class also lets you use [ ] array notation
+ * to access the <code>getItemAt()</code> and <code>setItemAt()</code> methods.
+ * If you use code such as <code>myListCollectionView[index]</code>
+ * Flex calls the <code>myListCollectionView</code> object's
+ * <code>getItemAt()</code> or <code>setItemAt()</code> method.</p>
+ *
+ * @mxml
+ *
+ * <p>The <code><mx:ListCollectionView></code> has the following attributes,
+ * which all of its subclasses inherit:</p>
+ *
+ * <pre>
+ * <mx:ListCollectionView
+ * <b>Properties</b>
+ * filterFunction="null"
+ * list="null"
+ * sort="null"
+ * <b>Events</b>
+ * collectionChange="<i>No default</i>"
+ * />
+ * </pre>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class ListCollectionView extends Proxy implements ICollectionView, IList //, IMXMLObject
+{
+// include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Private variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Change watcher for complex sort fields.
+ */
+ //private var _complexFieldWatcher:ComplexFieldChangeWatcher;
+
+ /**
+ * @private
+ * Internal event dispatcher.
+ */
+ private var eventDispatcher:EventDispatcher;
+
+ /**
+ * @private
+ * Revisions are used for bookmark maintenace,
+ * see getBookmark() and getBookmarkIndex() along with reset().
+ */
+ private var revision:int;
+
+ /**
+ * @private
+ * Used internally for managing disableAutoUpdate and enableAutoUpdate
+ * calls. disableAutoUpdate increments the counter, enable decrements.
+ * When the counter reaches 0 handlePendingUpdates is called.
+ */
+ private var autoUpdateCounter:int;
+
+ /**
+ * @private
+ * Any update events that occured while autoUpdateCounter > 0
+ * are stored here.
+ * This may be null when there are no updates.
+ */
+ private var pendingUpdates:Array;
+
+ /**
+ * @private
+ * Flag that indicates whether a RESET type of collectionChange
+ * event should be emitted when reset() is called.
+ */
+ mx_internal var dispatchResetEvent:Boolean = true;
+
+ /**
+ * @private
+ * Used for accessing localized Error messages.
+ */
+ //private var resourceManager:IResourceManager =
+ // ResourceManager.getInstance();
+
+ //--------------------------------------------------------------------------
+ //
+ // Protected variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * When the view is sorted or filtered the <code>localIndex</code> property
+ * contains an array of items in the sorted or filtered (ordered, reduced)
+ * view, in the sorted order.
+ * The ListCollectionView class uses this property to access the items in
+ * the view.
+ * The <code>localIndex</code> property should never contain anything
+ * that is not in the source, but may not have everything in the source.
+ * This property is <code>null</code> when there is no sort.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected var localIndex:Array;
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * The ListCollectionView constructor.
+ *
+ * @param list the IList this ListCollectionView is meant to wrap.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function ListCollectionView(list:IList = null)
+ {
+ super();
+
+ eventDispatcher = new EventDispatcher(this);
+ this.list = list;
+ }
+
+ /**
+ * Called automatically by the MXML compiler when the ListCollectionView
+ * is created using an MXML tag.
+ * If you create the ListCollectionView through ActionScript, you
+ * must call this method passing in the MXML document and
+ * <code>null</code> for the <code>id</code>.
+ *
+ * @param document The MXML document containing this ListCollectionView.
+ *
+ * @param id Ignored.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function initialized(document:Object, id:String):void
+ {
+ refresh();
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // length
+ //----------------------------------
+
+ [Bindable("collectionChange")]
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get length():int
+ {
+ if (localIndex)
+ {
+ return localIndex.length;
+ }
+ else if (list)
+ {
+ return list.length;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ //----------------------------------
+ // list
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the list property.
+ */
+ private var _list:IList;
+
+ [Inspectable(category="General")]
+ [Bindable("listChanged")]
+
+ /**
+ * The IList that this collection view wraps.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get list():IList
+ {
+ return _list;
+ }
+
+ /**
+ * @private
+ */
+ public function set list(value:IList):void
+ {
+ if (_list != value)
+ {
+ var oldHasItems:Boolean;
+ var newHasItems:Boolean;
+ if (_list)
+ {
+ _list.removeEventListener(CollectionEvent.COLLECTION_CHANGE, listChangeHandler);
+ oldHasItems = _list.length > 0;
+ }
+
+ _list = value;
+
+ if (_list)
+ {
+ // weak listeners to collections and dataproviders
+ //_list.addEventListener(CollectionEvent.COLLECTION_CHANGE, listChangeHandler, false, 0, true);
+ _list.addEventListener(CollectionEvent.COLLECTION_CHANGE, listChangeHandler, false);
+ newHasItems = _list.length > 0;
+ }
+
+ if (oldHasItems || newHasItems)
+ reset();
+ dispatchEvent(new Event("listChanged"));
+ }
+ }
+
+ //----------------------------------
+ // filterFunction
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the filterFunction property.
+ */
+ private var _filterFunction:Function;
+
+ [Bindable("filterFunctionChanged")]
+ [Inspectable(category="General")]
+
+ /**
+ * @inheritDoc
+ *
+ * @see #refresh()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get filterFunction():Function
+ {
+ return _filterFunction;
+ }
+
+ /**
+ * @private
+ */
+ public function set filterFunction(f:Function):void
+ {
+ _filterFunction = f;
+ dispatchEvent(new Event("filterFunctionChanged"));
+ }
+
+ //----------------------------------
+ // sort
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the sort property.
+ */
+ private var _sort:ISort;
+
+ [Bindable("sortChanged")]
+ [Inspectable(category="General")]
+
+ /**
+ * @inheritDoc
+ *
+ * @see #refresh()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get sort():ISort
+ {
+ return _sort;
+ }
+
+ /**
+ * @private
+ */
+ public function set sort(value:ISort):void
+ {
+ if(_sort != value)
+ {
+ //stopWatchingForComplexFieldsChanges();
+
+ _sort = value;
+
+ //startWatchingForComplexFieldsChanges();
+
+ dispatchEvent(new Event("sortChanged"));
+ }
+ }
+
+
+
+ //--------------------------------------------------------------------------
+ //
+ // ICollectionView Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @inheritDoc
+ *
+ * @see #enableAutoUpdate()
+ * @see mx.events.CollectionEvent
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function contains(item:Object):Boolean
+ {
+ return getItemIndex(item) != -1;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @see mx.collections.ICollectionView#enableAutoUpdate()
+ * @see mx.events.CollectionEvent
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function disableAutoUpdate():void
+ {
+ autoUpdateCounter++;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @see mx.collections.ICollectionView#disableAutoUpdate()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function enableAutoUpdate():void
+ {
+ if (autoUpdateCounter > 0)
+ {
+ autoUpdateCounter--;
+ if (autoUpdateCounter == 0)
+ {
+ handlePendingUpdates();
+ }
+ }
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function createCursor():IViewCursor
+ {
+ return new ListCollectionViewCursor(this);
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @see mx.events.CollectionEvent
+ * @see mx.core.IPropertyChangeNotifier
+ * @see mx.events.PropertyChangeEvent
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function itemUpdated(item:Object, property:Object = null,
+ oldValue:Object = null,
+ newValue:Object = null):void
+ {
+ list.itemUpdated(item, property, oldValue, newValue);
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function refresh():Boolean
+ {
+ return internalRefresh(true);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // IList Methods
+ //
+ //--------------------------------------------------------------------------
+
+ [Bindable("collectionChange")]
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function getItemAt(index:int, prefetch:int = 0):Object
+ {
+ /*
+ if (index < 0 || index >= length)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "outOfBounds", [ index ]);
+ throw new RangeError(message);
+ }
+ */
+
+ if (localIndex)
+ {
+ return localIndex[index];
+ }
+ else if (list)
+ {
+ return list.getItemAt(index, prefetch);
+ }
+
+ return null;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function setItemAt(item:Object, index:int):Object
+ {
+ /*
+ if (index < 0 || !list || index >= length)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "outOfBounds", [ index ]);
+ throw new RangeError(message);
+ }
+ */
+
+ var listIndex:int = index;
+ if (localIndex)
+ {
+ if (index > localIndex.length)
+ {
+ listIndex = list.length;
+ }
+ else
+ {
+ var oldItem:Object = localIndex[index];
+ // FIXME fails on duplicates
+ listIndex = list.getItemIndex(oldItem);
+ }
+ }
+ return list.setItemAt(item, listIndex);
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function addItem(item:Object):void
+ {
+ if (localIndex)
+ addItemAt(item, localIndex.length);
+ else
+ addItemAt(item, length);
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function addItemAt(item:Object, index:int):void
+ {
+ /*
+ if (index < 0 || !list || index > length)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "outOfBounds", [ index ]);
+ throw new RangeError(message);
+ }
+ */
+
+ var listIndex:int = index;
+
+ // if we're sorted addItemAt is meaningless, just add to the end
+ if (localIndex && sort)
+ {
+ listIndex = list.length;
+ }
+ else if (localIndex && filterFunction != null)
+ {
+ // if end of filtered list, put at end of source list
+ if (listIndex == localIndex.length)
+ listIndex = list.length;
+ // if somewhere in filtered list, find it and insert before it
+ // or at beginning
+ else
+ listIndex = list.getItemIndex(localIndex[index]);
+ }
+ // List is sorted or filtered but refresh has not been called
+ // Just add to end of list
+ else if (localIndex)
+ {
+ listIndex = list.length;
+ }
+
+ list.addItemAt(item, listIndex);
+ }
+
+ /**
+ * Adds a list of items to the current list, placing them at the end of
+ * the list in the order they are passed.
+ *
+ * @param addList IList The list of items to add to the current list
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function addAll(addList:IList):void
+ {
+ if (localIndex)
+ addAllAt(addList, localIndex.length);
+ else
+ addAllAt(addList, length);
+ }
+
+ /**
+ * Adds a list of items to the current list, placing them at the position
+ * index passed in to the function. The items are placed at the index location
+ * and placed in the order they are recieved.
+ *
+ * @param addList IList The list of items to add to the current list
+ * @param index The location of the current list to place the new items.
+ * @throws RangeError if index is less than 0 or greater than the length of the list.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function addAllAt(addList:IList, index:int):void
+ {
+ /*
+ if (index < 0 || index > this.length)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "outOfBounds", [ index ]);
+ throw new RangeError(message);
+ }
+ */
+
+ var length:int = addList.length;
+
+ for (var i:int=0; i < length; i++)
+ {
+ var insertIndex:int = i + index;
+
+ // incremental index may be out of bounds because of filtering,
+ // so add this item to the end.
+ if (insertIndex > this.length)
+ insertIndex = this.length;
+
+ this.addItemAt(addList.getItemAt(i), insertIndex);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function getItemIndex(item:Object):int
+ {
+ var i:int;
+
+ if (localIndex && filterFunction != null)
+ {
+ var len:int = localIndex.length;
+ for (i = 0; i < len; i++)
+ {
+ if (localIndex[i] == item)
+ return i;
+ }
+
+ return -1;
+ }
+ else if (localIndex && sort)
+ {
+ var startIndex:int = findItem(item, Sort.FIRST_INDEX_MODE);
+ if (startIndex == -1)
+ return -1;
+
+ var endIndex:int = findItem(item, Sort.LAST_INDEX_MODE);
+ for (i = startIndex; i <= endIndex; i++)
+ {
+ if (localIndex[i] == item)
+ return i;
+ }
+
+ return -1;
+ }
+ // List is sorted or filtered but refresh has not been called
+ else if (localIndex)
+ {
+ len = localIndex.length;
+ for (i = 0; i < len; i++)
+ {
+ if (localIndex[i] == item)
+ return i;
+ }
+
+ return -1;
+ }
+
+ // fallback
+ return list.getItemIndex(item);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ mx_internal function getLocalItemIndex(item:Object):int
+ {
+ var i:int;
+
+ var len:int = localIndex.length;
+ for (i = 0; i < len; i++)
+ {
+ if (localIndex[i] == item)
+ return i;
+ }
+
+ return -1;
+ }
+
+ /**
+ * @private
+ */
+ private function getFilteredItemIndex(item:Object):int
+ {
+ // loc is wrong
+ // the intent of this function is to find where this new item
+ // should be in the filtered list, by looking at the main list
+ // for it's neighbor that is also in this filtered list
+ // and trying to insert item after that neighbor in the insert locao filtered list
+
+ // 1st get the position in the original list
+ var loc:int = list.getItemIndex(item);
+
+ // something gone wrong and list is not filtered so just return loc to stop RTE
+ if (filterFunction == null)
+ return loc;
+
+ // if it's 0 then item must be also the first in the filtered list
+ if (loc == 0)
+ return 0;
+
+ // scan backwards for an item that also in the filtered list
+ for (var i:int = loc - 1; i >= 0; i--)
+ {
+ var prevItem:Object = list.getItemAt(i);
+ if (filterFunction(prevItem))
+ {
+ var len:int = localIndex.length;
+ // get the index of the item in the filtered set
+ // for (var j:int = 0; j < len; j++)
+ for (var j:int = 0; j < len; j++)
+ {
+ if (localIndex[j] == prevItem)
+ return j + 1;
+ }
+ }
+ }
+
+ // turns out that there are no neighbors of item in the filtered
+ // list, so item is the 1st item
+ return 0;
+ }
+
+ /**
+ * Removes the specified item from this list, should it exist.
+ * Relies on ArrayList implementation
+ *
+ * @param item Object reference to the item that should be removed.
+ * @return Boolean indicating if the item was removed.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Apache Flex 4.10
+ */
+ public function removeItem(item:Object):Boolean
+ {
+ if ("removeItem" in list)
+ return list["removeItem"](item);
+ return false;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function removeItemAt(index:int):Object
+ {
+ /*
+ if (index < 0 || index >= length)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "outOfBounds", [ index ]);
+ throw new RangeError(message);
+ }
+ */
+
+ var listIndex:int = index;
+ if (localIndex)
+ {
+ var oldItem:Object = localIndex[index];
+ listIndex = list.getItemIndex(oldItem);
+ }
+ return list.removeItemAt(listIndex);
+ }
+
+ /**
+ * Remove all items from the list.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function removeAll():void
+ {
+ var len:int = length;
+ if (len > 0)
+ {
+ if (localIndex && filterFunction != null)
+ {
+ len = localIndex.length;
+ for (var i:int = len - 1; i >= 0; i--)
+ {
+ removeItemAt(i);
+ }
+ }
+ else
+ {
+ localIndex = null;
+ list.removeAll();
+ }
+ }
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function toArray():Array
+ {
+ var ret:Array;
+ if (localIndex)
+ ret = localIndex.concat();
+ else
+ ret = list.toArray();
+ return ret;
+ }
+
+ /**
+ * Prints the contents of this view to a string and returns it.
+ *
+ * @return The contents of this view, in string form.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function toString():String
+ {
+ if (localIndex)
+ {
+ //return ObjectUtil.toString(localIndex);
+ return localIndex.toString();
+ }
+ else
+ {
+ if (list && Object(list).toString)
+ return Object(list).toString();
+ else
+ return getQualifiedClassName(this);
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Proxy methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Attempts to call getItemAt(), converting the property name into an int.
+ */
+ COMPILE::SWF
+ override flash_proxy function getProperty(name:*):*
+ {
+ if (name is QName)
+ name = name.localName;
+
+ return proxy_getProperty(name as String);
+ }
+ COMPILE::JS
+ override public function getProperty(name:String):*
+ {
+ return proxy_getProperty(name);
+ }
+
+ private function proxy_getProperty(name:String):*
+ {
+ try
+ {
+ var n:Number = parseInt(String(name));
+ }
+ catch(e:Error) // localName was not a number
+ {
+ }
+
+ /*
+ if (isNaN(n))
+ {
+ var message:String = resourceManager.getString(
+ "collections", "unknownProperty", [ name ]);
+ throw new Error(message);
+ }
+ else
+ {
+ */
+ // If caller passed in a number such as 5.5, it will be floored.
+ return getItemAt(int(n));
+ //}
+ }
+
+ /**
+ * @private
+ * Attempts to call setItemAt(), converting the property name into an int.
+ */
+ COMPILE::SWF
+ override flash_proxy function setProperty(name:*, value:*):void
+ {
+ if (name is QName)
+ name = name.localName;
+ proxy_setProperty(name as String, value);
+ }
+ COMPILE::JS
+ override public function setProperty(name:String, value:*):void
+ {
+ proxy_setProperty(name as String, value);
+ }
+
+ private function proxy_setProperty(name:String, value:*):void
+ {
+
+ try
+ {
+ var n:Number = parseInt(String(name));
+ }
+ catch(e:Error) // localName was not a number
+ {
+ }
+
+ /*
+ if (isNaN(n))
+ {
+ var message:String = resourceManager.getString(
+ "collections", "unknownProperty", [ name ]);
+ throw new Error(message);
+ }
+ else
+ {
+ */
+ // If caller passed in a number such as 5.5, it will be floored.
+ setItemAt(value, int(n));
+ //}
+ }
+
+ /**
+ * @private
+ * This is an internal function.
+ * The VM will call this method for code like <code>"foo" in bar</code>
+ *
+ * @param name The property name that should be tested for existence.
+ */
+ COMPILE::SWF
+ override flash_proxy function hasProperty(name:*):Boolean
+ {
+ if (name is QName)
+ name = name.localName;
+
+ return proxy_hasProperty(name as String);
+ }
+ COMPILE::JS
+ override public function hasProperty(name:String):Boolean
+ {
+ return proxy_hasProperty(name as String);
+ }
+
+ private function proxy_hasProperty(name:String):Boolean
+ {
+ var index:int = -1;
+ try
+ {
+ // If caller passed in a number such as 5.5, it will be floored.
+ var n:Number = parseInt(String(name));
+ if (!isNaN(n))
+ index = int(n);
+ }
+ catch(e:Error) // localName was not a number
+ {
+ }
+
+ if (index == -1)
+ return false;
+
+ return index >= 0 && index < length;
+ }
+
+ /**
+ * @private
+ */
+ COMPILE::SWF
+ override flash_proxy function nextNameIndex(index:int):int
+ {
+ return index < length ? index + 1 : 0;
+ }
+
+ /**
+ * @private
+ */
+ COMPILE::SWF
+ override flash_proxy function nextName(index:int):String
+ {
+ return (index - 1).toString();
+ }
+
+ /**
+ * @private
+ */
+ COMPILE::SWF
+ override flash_proxy function nextValue(index:int):*
+ {
+ return getItemAt(index - 1);
+ }
+
+ /**
+ * @private
+ * Any methods that can't be found on this class shouldn't be called,
+ * so return null
+ */
+ COMPILE::SWF
+ override flash_proxy function callProperty(name:*, ... rest):*
+ {
+ return null;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // EventDispatcher methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ COMPILE::SWF
+ public function addEventListener(eventType:String,
+ listener:Function,
+ useCapture:Boolean = false,
+ priority:int = 0,
+ useWeakReference:Boolean = false):void
+ {
+ eventDispatcher.addEventListener(eventType, listener, useCapture,
+ priority, useWeakReference);
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ COMPILE::SWF
+ public function removeEventListener(eventType:String,
+ listener:Function,
+ useCapture:Boolean = false):void
+ {
+ eventDispatcher.removeEventListener(eventType, listener, useCapture);
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ COMPILE::SWF
+ public function dispatchEvent(event:Event):Boolean
+ {
+ return eventDispatcher.dispatchEvent(event);
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ COMPILE::SWF
+ public function hasEventListener(eventType:String):Boolean
+ {
+ return eventDispatcher.hasEventListener(eventType);
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ COMPILE::SWF
+ public function willTrigger(eventType:String):Boolean
+ {
+ return eventDispatcher.willTrigger(eventType);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Internal methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Take the item and insert it into the view. If we don't have a sort
+ * use the sourceLocation. Dispatch the CollectionEvent with kind ADD
+ * if dispatch is true.
+ *
+ * @param items the items to add into the view
+ * @param sourceLocation the location within the list where the items were added
+ * @param dispatch true if the view should dispatch a corresponding
+ * CollectionEvent with kind ADD (default is true)
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function addItemsToView(items:Array, sourceLocation:int,
+ dispatch:Boolean = true):int
+ {
+ var addedItems:Array = localIndex ? [] : items;
+ var addLocation:int = sourceLocation;
+ var firstOne:Boolean = true;
+
+ if (localIndex)
+ {
+ var loc:int = sourceLocation;
+ var length:int = items.length;
+
+ for (var i:int = 0; i < length; i++)
+ {
+ var item:Object = items[i];
+
+ if (filterFunction != null)
+ {
+ if (filterFunction(item))
+ {
+ if (sort)
+ loc = findItem(item, Sort.ANY_INDEX_MODE, true);
+ else
+ loc = getFilteredItemIndex(item);
+
+ if (firstOne)
+ {
+ addLocation = loc;
+ firstOne = false;
+ }
+ }
+ else
+ {
+ loc = -1;
+ addLocation = -1;
+ }
+ }
+ else if (sort)
+ {
+ loc = findItem(item, Sort.ANY_INDEX_MODE, true);
+ if (firstOne)
+ {
+ addLocation = loc;
+ firstOne = false;
+ }
+ }
+ else
+ // List is sorted or filtered but refresh has not been called
+ // Just add to end of list
+ {
+ loc = localIndex.length;
+ addLocation = loc;
+ }
+
+ if (loc != -1)
+ {
+ localIndex.splice(loc++, 0, item);
+ addedItems.push(item);
+ }
+ }
+ }
+
+ /*
+ if (sort && sort.unique && sort.compareFunction(item, localIndex[loc]) == 0)
+ {
+ // We cause all adds to fail here, not just the one.
+ var message:String = resourceManager.getString(
+ "collections", "incorrectAddition");
+ throw new CollectionViewError(message);
+ }
+ */
+
+ if (localIndex && addedItems.length > 1)
+ {
+ addLocation = -1;
+ }
+
+ if (dispatch && addedItems.length > 0)
+ {
+ var event:CollectionEvent =
+ new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = CollectionEventKind.ADD;
+ event.location = addLocation;
+ event.items = addedItems;
+ dispatchEvent(event);
+ }
+
+ return addLocation;
+ }
+
+ /**
+ * Find the item specified using the Sort find mode constants.
+ * If there is no sort assigned throw an error.
+ *
+ * @param values the values object that can be passed into Sort.findItem
+ * @param mode the mode to pass to Sort.findItem (see Sort)
+ * @param insertIndex true if it should find the insertion point
+ * @return the index where the item is located, -1 if not found or SortError
+ * caught
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ mx_internal function findItem(values:Object, mode:String, insertIndex:Boolean = false):int
+ {
+ /*
+ if (!sort || !localIndex)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "itemNotFound");
+ throw new CollectionViewError(message);
+ }
+ */
+
+ if (localIndex.length == 0)
+ return insertIndex ? 0 : -1;
+
+ try
+ {
+ return sort.findItem(localIndex, values, mode, insertIndex);
+ }
+ catch (e:SortError)
+ {
+ // usually because the find criteria is not compatible with the sort.
+ }
+
+ return -1;
+ }
+
+ /**
+ * Create a bookmark for this view. This method is called by
+ * ListCollectionViewCursor.
+ *
+ * @param index the index to bookmark
+ * @return a new bookmark instance
+ * @throws a CollectionViewError if the index is out of bounds
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ mx_internal function getBookmark(index:int):ListCollectionViewBookmark
+ {
+ /*
+ if (index < 0 || index > length)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "invalidIndex", [ index ]);
+ throw new CollectionViewError(message);
+ }
+ */
+
+ var value:Object;
+ try
+ {
+ value = getItemAt(index);
+ }
+ catch(e:Error)
+ {
+ }
+ return new ListCollectionViewBookmark(value,
+ this,
+ revision,
+ index);
+
+ }
+
+ /**
+ * Given a bookmark find the location for the value. If the
+ * view has been modified since the bookmark was created attempt
+ * to relocate the item. If the bookmark represents an item
+ * that is no longer in the view (removed or filtered out) return
+ * -1.
+ *
+ * @param bookmark the bookmark to locate
+ * @return the new location of the bookmark, -1 if not in the view anymore
+ * @throws CollectionViewError if the bookmark is invalid
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ mx_internal function getBookmarkIndex(bookmark:CursorBookmark):int
+ {
+ /*
+ if (!(bookmark is ListCollectionViewBookmark)
+ || ListCollectionViewBookmark(bookmark).view != this)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "bookmarkNotFound");
+ throw new CollectionViewError(message);
+ }
+ */
+
+ var bm:ListCollectionViewBookmark = ListCollectionViewBookmark(bookmark);
+
+ if (bm.viewRevision != revision)
+ {
+ // getItemAt has a side-effect of throwing an exception if the index is out-
+ // of-range, here we are checking to see if the index falls with-in the range
+ // and only then calling getItemAt.
+ if (bm.index < 0 || bm.index >= length || getItemAt(bm.index) != bm.value)
+ {
+ try
+ {
+ bm.index = getItemIndex(bm.value);
+ }
+ catch (e:SortError)
+ {
+ bm.index = getLocalItemIndex(bm.value);
+ }
+ }
+
+ bm.viewRevision = revision;
+ }
+ return bm.index;
+ }
+
+ /**
+ * The view is a listener of CollectionEvents on its underlying IList
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function listChangeHandler(event:CollectionEvent):void
+ {
+ if (autoUpdateCounter > 0)
+ {
+ if (!pendingUpdates)
+ {
+ pendingUpdates = [];
+ }
+ pendingUpdates.push(event);
+ }
+ else
+ {
+ switch (event.kind)
+ {
+ case CollectionEventKind.ADD:
+ addItemsToView(event.items, event.location);
+ break;
+
+ case CollectionEventKind.MOVE:
+ var n:int = event.items.length;
+ for (var i:int = 0; i < n; i++)
+ moveItemInView(event.items[i]);
+ break;
+
+ case CollectionEventKind.RESET:
+ reset();
+ break;
+
+ case CollectionEventKind.REMOVE:
+ removeItemsFromView(event.items, event.location);
+ break;
+
+ case CollectionEventKind.REPLACE:
+ replaceItemsInView(event.items, event.location);
+ break;
+
+ case CollectionEventKind.UPDATE:
+ handlePropertyChangeEvents(event.items);
+ break;
+
+ default:
+ dispatchEvent(event);
+ } // switch
+ }
+ }
+
+ /**
+ * Given a set of <code>PropertyChangeEvent</code>s go through and update the view.
+ * This is currently not optimized.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function handlePropertyChangeEvents(events:Array):void
+ {
+ var eventItems:Array = events;
+ if (sort || filterFunction != null)
+ {
+ //go through the events and find all the individual objects
+ //that have been updated
+ //then for each one determine whether we should move it or
+ //just fire an update event
+ var updatedItems:Array = [];
+ var updateEntry:Object;
+ var i:int;
+ for (i = 0; i < events.length; i++)
+ {
+ var updateInfo:PropertyChangeEvent = events[i];
+ var item:Object;
+ var defaultMove:Boolean;
+ if (updateInfo.target)
+ {
+ item = updateInfo.target;
+ //if the target != source that means the update
+ //happened to some sub-property of the item in the collection.
+ //if we have a custom comparator this will affect
+ //the sort so for now say we should move but
+ //maybe we could optimize further
+ defaultMove = updateInfo.target != updateInfo.source;
+ }
+ else
+ {
+ item = updateInfo.source;
+ defaultMove = false;
+ }
+
+ //see if the item is already in the list
+ var j:int = 0;
+ for (; j < updatedItems.length; j++)
+ {
+ if (updatedItems[j].item == item)
+ {
+ // even if it is, if a different property changed, track that too.
+ var evts:Array = updatedItems[j].events as Array;
+ var l:int = evts.length;
+ for (var k:int = 0; k < l; k++)
+ {
+ if (evts[k].property != updateInfo.property)
+ {
+ evts.push(updateInfo);
+ break;
+ }
+ // we could also merge events for changes to the same
+ // property but that's hopefully low probability
+ // and leads to questions of event order.
+ }
+ break;
+ }
+ }
+
+ if (j < updatedItems.length)
+ {
+ updateEntry = updatedItems[j];
+ }
+ else
+ {
+ var oldOrNewValueSpecified:Boolean = updateInfo.oldValue != null || updateInfo.newValue != null;
+ var objectReplacedInCollection:Boolean = updateInfo.property == null && oldOrNewValueSpecified;
+ var somethingUnknownAboutTheObjectChanged:Boolean = updateInfo.property == null && !oldOrNewValueSpecified;
+ updateEntry = {item: item, move: defaultMove, events: [updateInfo],
+ undefinedChange:somethingUnknownAboutTheObjectChanged,
+ objectReplacedWithAnother: objectReplacedInCollection, oldItem: updateInfo.oldValue};
+ updatedItems.push(updateEntry);
+ }
+
+ //if we've already set move don't unset it
+ //if there's a filterFunction need to go through move
+ //if the property affects the sort, we'll need to move
+ updateEntry.move = updateEntry.move
+ || filterFunction != null
+ || updateEntry.objectReplacedWithAnother
+ || updateEntry.undefinedChange
+ || (sort && sort.propertyAffectsSort(String(updateInfo.property)));
+ }
+
+ // go through the items and move and send move events for ones that moved
+ // and build the list of remaining items we need to send UPDATE events for
+ eventItems = [];
+ for (i = 0; i < updatedItems.length; i++)
+ {
+ updateEntry = updatedItems[i];
+ if (updateEntry.move)
+ {
+ if(updateEntry.objectReplacedWithAnother)
+ {
+ removeItemsFromView([updateEntry.oldItem], -1, true);
+ }
+ moveItemInView(updateEntry.item, updateEntry.item != null, eventItems);
+ }
+ else
+ {
+ eventItems.push(updateEntry.item);
+ }
+ }
+
+ // now go through the updated items and add all events for all
+ // properties that changed in that item (except for those items
+ // we moved)
+ var temp:Array = [];
+ for (var ctr:int = 0; ctr < eventItems.length; ctr++)
+ for (var ctr1:int = 0; ctr1 < updatedItems.length; ctr1++)
+ if (eventItems[ctr] == updatedItems[ctr1].item)
+ {
+ temp = temp.concat(updatedItems[ctr1].events);
+ }
+ eventItems = temp;
+ }
+
+ if (eventItems.length > 0)
+ {
+ var updateEvent:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ updateEvent.kind = CollectionEventKind.UPDATE;
+ updateEvent.items = eventItems;
+ dispatchEvent(updateEvent);
+ }
+ }
+
+ /**
+ * When enableAutoUpdates pushes autoUpdateCounter back down to 0
+ * this method will execute to consolidate the pending update
+ * events or turn it into a massive refresh().
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function handlePendingUpdates():void
+ {
+ if (pendingUpdates)
+ {
+ var pu:Array = pendingUpdates;
+ pendingUpdates = null;
+
+ // Could further optimize to consolidate various events
+ // and make a decision if there are too many updates
+ // and we should just refresh.
+ var singleUpdateEvent:CollectionEvent;
+ for (var i:int = 0; i < pu.length; i++)
+ {
+ var event:CollectionEvent = pu[i];
+ if (event.kind == CollectionEventKind.UPDATE)
+ {
+ if (!singleUpdateEvent)
+ {
+ singleUpdateEvent = event;
+ }
+ else
+ {
+ for (var j:int = 0; j < event.items.length; j++)
+ {
+ singleUpdateEvent.items.push(event.items[j]);
+ }
+ }
+ }
+ else
+ {
+ listChangeHandler(event);
+ }
+ }
+
+ if (singleUpdateEvent)
+ {
+ listChangeHandler(singleUpdateEvent);
+ }
+ }
+ }
+
+ private function internalRefresh(dispatch:Boolean):Boolean
+ {
+ if (sort || filterFunction != null)
+ {
+ /*
+ try
+ {
+ */
+ populateLocalIndex();
+ /*
+ }
+ catch(pending:ItemPendingError)
+ {
+ pending.addResponder(new ItemResponder(
+ function(data:Object, token:Object = null):void
+ {
+ internalRefresh(dispatch);
+ },
+ function(info:Object, token:Object = null):void
+ {
+ //no-op
+ }));
+ return false;
+ }
+ */
+
+ if (filterFunction != null)
+ {
+ var tmp:Array = [];
+ var len:int = localIndex.length;
+ for (var i:int = 0; i < len; i++)
+ {
+ var item:Object = localIndex[i];
+ if (filterFunction(item))
+ {
+ tmp.push(item);
+ }
+ }
+ localIndex = tmp;
+ }
+
+ if (sort)
+ {
+ sort.sort(localIndex);
+ dispatch = true;
+ }
+ }
+ else if (localIndex)
+ {
+ localIndex = null;
+ }
+
+ revision++;
+ pendingUpdates = null;
+ if (dispatch)
+ {
+ var refreshEvent:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ refreshEvent.kind = CollectionEventKind.REFRESH;
+ dispatchEvent(refreshEvent);
+ }
+ return true;
+ }
+
+ /**
+ * Remove the old value from the view and replace it with the value
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function moveItemInView(item:Object, dispatch:Boolean = true, updateEventItems:Array = null):void
+ {
+ if (localIndex)
+ {
+ //we're guaranteed that removeItemsFromView isn't going
+ //to work here because the item has probably
+ //already been updated so getItemIndex is going to fail
+ //so we'll just do a linear search and find it if it's here
+ var removeLocation:int = -1;
+ for (var i:int = 0; i < localIndex.length; i++)
+ {
+ if (localIndex[i] == item)
+ {
+ removeLocation = i;
+ break;
+ }
+ }
+ if (removeLocation > -1)
+ {
+ localIndex.splice(removeLocation, 1);
+ }
+
+ var addLocation:int = addItemsToView([item], removeLocation, false);
+
+ if (dispatch)
+ {
+ var event:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.items.push(item);
+ if (updateEventItems && addLocation == removeLocation && addLocation > -1)
+ {
+ updateEventItems.push(item);
+ return;
+ }
+ if (addLocation > -1 && removeLocation > -1)
+ {
+ event.kind = CollectionEventKind.MOVE;
+ event.location = addLocation;
+ event.oldLocation = removeLocation;
+ }
+ else if (addLocation > -1)
+ {
+ event.kind = CollectionEventKind.ADD;
+ event.location = addLocation;
+ }
+ else if (removeLocation > -1)
+ {
+ event.kind = CollectionEventKind.REMOVE;
+ event.location = removeLocation;
+ }
+ else
+ {
+ dispatch = false;
+ }
+
+ if (dispatch)
+ {
+ dispatchEvent(event);
+ }
+ }
+ }
+ }
+
+ /**
+ * Copy all of the data from the source list into the local index.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function populateLocalIndex():void
+ {
+ if (list)
+ {
+ localIndex = list.toArray();
+ }
+ else
+ {
+ localIndex = [];
+ }
+ }
+
+ /**
+ * Take the item and remove it from the view. If we don't have a sort
+ * use the sourceLocation. Dispatch the CollectionEvent with kind REMOVE
+ * if dispatch is true.
+ *
+ * @param items the items to remove from the view
+ * @param sourceLocation the location within the list where the item was removed
+ * @param dispatch true if the view should dispatch a corresponding
+ * CollectionEvent with kind REMOVE (default is true)
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function removeItemsFromView(items:Array, sourceLocation:int, dispatch:Boolean = true):void
+ {
+ var removedItems:Array = localIndex ? [] : items;
+ var removeLocation:int = sourceLocation;
+ if (localIndex)
+ {
+ for (var i:int = 0; i < items.length; i++)
+ {
+ var item:Object = items[i];
+ var loc:int = getItemIndex(item);
+ if (loc > -1)
+ {
+ localIndex.splice(loc, 1);
+ removedItems.push(item);
+ removeLocation = loc;
+ }
+ }
+ }
+ if (dispatch && removedItems.length > 0)
+ {
+ var event:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = CollectionEventKind.REMOVE;
+ event.location = (!localIndex || removedItems.length == 1)
+ ? removeLocation
+ : -1;
+ event.items = removedItems;
+ dispatchEvent(event);
+ }
+ }
+
+ /**
+ * Items is an array of PropertyChangeEvents so replace the oldValues with the new
+ * newValues. Start at the location specified and move forward, it's unlikely
+ * that the length of items is > 1.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function replaceItemsInView(changeEvents:Array,
+ location:int,
+ dispatch:Boolean = true):void
+ {
+ if (localIndex)
+ {
+ var len:int = changeEvents.length;
+ var oldItems:Array = [];
+ var newItems:Array = [];
+ for (var i:int = 0; i < len; i++)
+ {
+ var propertyEvent:PropertyChangeEvent = changeEvents[i];
+ oldItems.push(propertyEvent.oldValue);
+ newItems.push(propertyEvent.newValue);
+ }
+ removeItemsFromView(oldItems, location, dispatch);
+ addItemsToView(newItems, location, dispatch);
+ }
+ else
+ {
+ var event:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = CollectionEventKind.REPLACE;
+ event.location = location;
+ event.items = changeEvents;
+ dispatchEvent(event);
+ }
+ }
+
+ /**
+ * @private
+ * When the source list is replaced, reset.
+ */
+ mx_internal function reset():void
+ {
+ internalRefresh(false);
+ if (dispatchResetEvent)
+ {
+ var event:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = CollectionEventKind.RESET;
+ dispatchEvent(event);
+ }
+ }
+
+ /*
+ public function get complexFieldWatcher():ComplexFieldChangeWatcher
+ {
+ return _complexFieldWatcher;
+ }
+
+ public function set complexFieldWatcher(value:ComplexFieldChangeWatcher):void
+ {
+ if(_complexFieldWatcher != value)
+ {
+ stopWatchingForComplexFieldsChanges();
+
+ _complexFieldWatcher = value;
+ if(_complexFieldWatcher)
+ _complexFieldWatcher.mx_internal::list = this;
+
+ startWatchingForComplexFieldsChanges();
+ }
+ }
+
+ private function startWatchingForComplexFieldsChanges():void
+ {
+ if(complexFieldWatcher && sort && sort.fields)
+ {
+ _complexFieldWatcher.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, onComplexFieldValueChanged, false, 0, true);
+ _complexFieldWatcher.startWatchingForComplexFieldChanges();
+ }
+ }
+
+ private function stopWatchingForComplexFieldsChanges():void
+ {
+ if(complexFieldWatcher)
+ {
+ _complexFieldWatcher.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE, onComplexFieldValueChanged);
+ _complexFieldWatcher.stopWatchingForComplexFieldChanges();
+ }
+ }
+
+ private function onComplexFieldValueChanged(changeEvent:PropertyChangeEvent):void
+ {
+ if(sort)
+ {
+ moveItemInView(changeEvent.source);
+ }
+ }
+ */
+}
+
+}
+
+import org.apache.royale.events.EventDispatcher;
+
+import mx.collections.*;
+import mx.collections.errors.*;
+import mx.core.mx_internal;
+import mx.events.*;
+//import mx.resources.IResourceManager;
+//import mx.resources.ResourceManager;
+
+use namespace mx_internal;
+
+/**
+ * Dispatched whenever the cursor position is updated.
+ *
+ * @eventType mx.events.FlexEvent.CURSOR_UPDATE
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+[Event(name="cursorUpdate", type="mx.events.FlexEvent")]
+
+[ResourceBundle("collections")]
+
+/**
+ * @private
+ * The internal implementation of cursor for the ListCollectionView.
+ */
+class ListCollectionViewCursor extends EventDispatcher implements IViewCursor
+{
+ //--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ private static const BEFORE_FIRST_INDEX:int = -1;
+
+ /**
+ * @private
+ */
+ private static const AFTER_LAST_INDEX:int = -2;
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * <p>Creates the cursor for the view.</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function ListCollectionViewCursor(view:ListCollectionView)
+ {
+ super();
+
+ _view = view;
+ _view.addEventListener(CollectionEvent.COLLECTION_CHANGE, collectionEventHandler);
+ //_view.addEventListener(CollectionEvent.COLLECTION_CHANGE, collectionEventHandler, false, 0, true);
+ currentIndex = view.length > 0 ? 0 : AFTER_LAST_INDEX;
+ if (currentIndex == 0)
+ {
+ /*
+ try
+ {
+ */
+ setCurrent(view.getItemAt(0), false);
+ /*
+ }
+ catch(e:ItemPendingError)
+ {
+ currentIndex = BEFORE_FIRST_INDEX;
+ setCurrent(null, false);
+ }
+ */
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ private var _view:ListCollectionView;
+
+ /**
+ * @private
+ */
+ private var currentIndex:int;
+
+ /**
+ * @private
+ */
+ private var currentValue:Object;
+
+ /**
+ * @private
+ */
+ private var invalid:Boolean;
+
+ /**
+ * @private
+ * Used for accessing localized Error messages.
+ */
+ //private var resourceManager:IResourceManager =
+ // ResourceManager.getInstance();
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Get a reference to the view that this cursor is associated with.
+ * @return the associated <code>ICollectionView</code>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get view():ICollectionView
+ {
+ checkValid();
+ return _view;
+ }
+
+ [Bindable("cursorUpdate")]
+ /**
+ * Provides access the object at the current location referenced by
+ * this cursor within the source collection.
+ * If the cursor is beyond the ends of the collection (beforeFirst,
+ * afterLast) this will return <code>null</code>.
+ *
+ * @see mx.collections.IViewCursor#moveNext
+ * @see mx.collections.IViewCursor#movePrevious
+ * @see mx.collections.IViewCursor#seek
+ * @see mx.collections.IViewCursor#beforeFirst
+ * @see mx.collections.IViewCursor#afterLast
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get current():Object
+ {
+ checkValid();
+
+ return currentValue;
+ }
+
+ [Bindable("cursorUpdate")]
+
+ /**
+ * Provides access to the bookmark of the item returned by the
+ * <code>current</code> property.
+ * The bookmark can be used to move the cursor to a previously visited
+ * item, or one relative to it (see the <code>seek()</code> method for
+ * more information).
+ *
+ * @see mx.collections.IViewCursor#current
+ * @see mx.collections.IViewCursor#seek
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get bookmark():CursorBookmark
+ {
+ checkValid();
+ if (view.length == 0 || beforeFirst) return CursorBookmark.FIRST;
+ else if (afterLast) return CursorBookmark.LAST;
+ //if currentIndex > view.length this is a bug in cursor and i want the
+ //exception thrown to track it down
+ else return ListCollectionView(view).getBookmark(currentIndex);
+ }
+
+
+ [Bindable("cursorUpdate")]
+ /**
+ * true if the current is sitting before the first item in the view.
+ * If the ICollectionView is empty (length == 0) this will always
+ * be true.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get beforeFirst():Boolean
+ {
+ checkValid();
+ return currentIndex == BEFORE_FIRST_INDEX || view.length == 0;
+ }
+
+
+ [Bindable("cursorUpdate")]
+ /**
+ * true if the cursor is sitting after the last item in the view.
+ * If the ICollectionView is empty (length == 0) this will always
+ * be true.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get afterLast():Boolean
+ {
+ checkValid();
+ return currentIndex == AFTER_LAST_INDEX || view.length == 0;
+ }
+
+ /**
+ * Finds the item with the specified properties within the
+ * collection and positions the cursor on that item.
+ * If the item can not be found no change to the current location will be
+ * made.
+ * <code>findAny()</code> can only be called on sorted views, if the view
+ * isn't sorted, or items in the view do not contain properties used
+ * to compute the sort order, a <code>CursorError</code> will be thrown.
+ * <p>
+ * If the associated collection is remote, and not all of the items have
+ * been cached locally this method will begin an asynchronous fetch from the
+ * remote collection, or if one is already in progress wait for it to
+ * complete before making another fetch request.
+ * If multiple items can match the search criteria then the item found is
+ * non-deterministic.
+ * If it is important to find the first or last occurrence of an item in a
+ * non-unique index use the <code>findFirst()</code> or
+ * <code>findLast()</code>.
+ * The values specified must be configured as name-value pairs, as in an
+ * associative array (or the actual object to search for).
+ * The values of the names specified must match those properties specified in
+ * the sort. for example
+ * If properties "x", "y", and "z" are the in the current index, the values
+ * specified should be {x:x-value, y:y-value,z:z-value}.
+ * When all of the data is local this method will return <code>true</code> if
+ * the item can be found and false otherwise.
+ * If the data is not local and an asynchronous operation must be performed,
+ * an <code>ItemPendingError</code> will be thrown.
+ *
+ * @see mx.collections.IViewCursor#findFirst
+ * @see mx.collections.IViewCursor#findLast
+ * @see mx.collections.errors.ItemPendingError
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function findAny(values:Object):Boolean
+ {
+ checkValid();
+ var lcView:ListCollectionView = ListCollectionView(view);
+ var index:int;
+ try
+ {
+ index = lcView.findItem(values, Sort.ANY_INDEX_MODE);
+ }
+ catch(e:SortError)
+ {
+ //this is because the find critieria is not compatible with the
+ //sort
+ throw new CursorError(e.message);
+ }
+ if (index > -1)
+ {
+ currentIndex = index;
+ setCurrent(lcView.getItemAt(currentIndex));
+ }
+ return index > -1;
+ }
+
+ /**
+ * Finds the first item with the specified properties
+ * within the collection and positions the cursor on that item.
+ * If the item can not be found no change to the current location will be
+ * made.
+ * <code>findFirst()</code> can only be called on sorted views, if the view
+ * isn't sorted, or items in the view do not contain properties used
+ * to compute the sort order, a <code>CursorError</code> will be thrown.
+ * <p>
+ * If the associated collection is remote, and not all of the items have been
+ * cached locally this method will begin an asynchronous fetch from the
+ * remote collection, or if one is already in progress wait for it to
+ * complete before making another fetch request.
+ * If it is not important to find the first occurrence of an item in a
+ * non-unique index use <code>findAny()</code> as it may be a little faster.
+ * The values specified must be configured as name-value pairs, as in an
+ * associative array (or the actual object to search for).
+ * The values of the names specified must match those properties specified in
+ * the sort. for example If properties "x", "y", and "z" are the in the current
+ * index, the values specified should be {x:x-value, y:y-value,z:z-value}.
+ * When all of the data is local this method will
+ * return <code>true</code> if the item can be found and false otherwise.
+ * If the data is not local and an asynchronous operation must be performed,
+ * an <code>ItemPendingError</code> will be thrown.
+ *
+ * @see mx.collections.IViewCursor#findAny
+ * @see mx.collections.IViewCursor#findLast
+ * @see mx.collections.errors.ItemPendingError
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function findFirst(values:Object):Boolean
+ {
+ checkValid();
+ var lcView:ListCollectionView = ListCollectionView(view);
+ var index:int;
+ try
+ {
+ index = lcView.findItem(values, Sort.FIRST_INDEX_MODE);
+ }
+ catch(sortError:SortError)
+ {
+ //this is because the find critieria is not compatible with the
+ //sort
+ throw new CursorError(sortError.message);
+ }
+ if (index > -1)
+ {
+ currentIndex = index;
+ setCurrent(lcView.getItemAt(currentIndex));
+ }
+ return index > -1;
+ }
+
+
+ /**
+ * Finds the last item with the specified properties
+ * within the collection and positions the cursor on that item.
+ * If the item can not be found no change to the current location will be
+ * made.
+ * <code>findLast()</code> can only be called on sorted views, if the view
+ * isn't sorted, or items in the view do not contain properties used
+ * to compute the sort order, a <code>CursorError</code> will be thrown.
+ * <p>
+ * If the associated collection is remote, and not all of the items have been
+ * cached locally this method will begin an asynchronous fetch from the
+ * remote collection, or if one is already in progress wait for it to
+ * complete before making another fetch request.
+ * If it is not important to find the last occurrence of an item in a
+ * non-unique index use <code>findAny()</code> as it may be a little faster.
+ * The values specified must be configured as name-value pairs, as in an
+ * associative array (or the actual object to search for).
+ * The values of the names specified must match those properties specified in
+ * the sort. for example If properties "x", "y", and "z" are the in the current
+ * index, the values specified should be {x:x-value, y:y-value,z:z-value}.
+ * When all of the data is local this method will
+ * return <code>true</code> if the item can be found and false otherwise.
+ * If the data is not local and an asynchronous operation must be performed,
+ * an <code>ItemPendingError</code> will be thrown.
+ *
+ * @see mx.collections.IViewCursor#findAny
+ * @see mx.collections.IViewCursor#findFirst
+ * @see mx.collections.errors.ItemPendingError
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function findLast(values:Object):Boolean
+ {
+ checkValid();
+ var lcView:ListCollectionView = ListCollectionView(view);
+ var index:int;
+ try
+ {
+ index = lcView.findItem(values, Sort.LAST_INDEX_MODE);
+ }
+ catch(sortError:SortError)
+ {
+ //this is because the find critieria is not compatible with the
+ //sort
+ throw new CursorError(sortError.message);
+ }
+ if (index > -1)
+ {
+ currentIndex = index;
+ setCurrent(lcView.getItemAt(currentIndex));
+ }
+ return index > -1;
+ }
+
+ /**
+ * Insert the specified item before the cursor's current position.
+ * If the cursor is <code>afterLast</code> the insertion
+ * will happen at the end of the View. If the cursor is
+ * <code>beforeFirst</code> on a non-empty view an error will be thrown.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function insert(item:Object):void
+ {
+ var insertIndex:int;
+ if (afterLast)
+ {
+ insertIndex = view.length;
+ }
+ else if (beforeFirst)
+ {
+ if (view.length > 0)
+ {
+ var message:String = /*resourceManager.getString(
+ "collections", */"invalidInsert"/*)*/;
+ throw new CursorError(message);
+ }
+ else
+ {
+ insertIndex = 0;
+ }
+ }
+ else
+ {
+ insertIndex = currentIndex;
+ }
+ ListCollectionView(view).addItemAt(item, insertIndex);
+ }
+
+ /**
+ * Moves the cursor to the next item within the collection. On success
+ * the <code>current</code> property will be updated to reference the object at this
+ * new location. Returns true if current is valid, false if not (afterLast).
+ * If the data is not local and an asynchronous operation must be performed, an
+ * <code>ItemPendingError</code> will be thrown. See the ItemPendingError docs
+ * as well as the collections documentation for more information on using the
+ * ItemPendingError.
+ *
+ * @return true if still in the list, false if current is now afterLast
+ *
+ * @see mx.collections.IViewCursor#current
+ * @see mx.collections.IViewCursor#movePrevious
+ * @see mx.collections.errors.ItemPendingError
+ * @example
+ * <pre>
+ * var myArrayCollection:ICollectionView = new ArrayCollection(["Bobby", "Mark", "Trevor", "Jacey", "Tyler"]);
+ * var cursor:IViewCursor = myArrayCollection.createCursor();
+ * while (!cursor.afterLast)
+ * {
+ * trace(cursor.current);
+ * cursor.moveNext();
+ * }
+ * </pre>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function moveNext():Boolean
+ {
+ //the afterLast getter checks validity and also checks length > 0
+ if (afterLast)
+ {
+ return false;
+ }
+ // we can't set the index until we know that we can move there first.
+ var tempIndex:int = beforeFirst ? 0 : currentIndex + 1;
+ if (tempIndex >= view.length)
+ {
+ tempIndex = AFTER_LAST_INDEX;
+ setCurrent(null);
+ }
+ else
+ {
+ setCurrent(ListCollectionView(view).getItemAt(tempIndex));
+ }
+ currentIndex = tempIndex;
+ return !afterLast;
+ }
+
+ /**
+ * Moves the cursor to the previous item within the collection. On success
+ * the <code>current</code> property will be updated to reference the object at this
+ * new location. Returns true if current is valid, false if not (beforeFirst).
+ * If the data is not local and an asynchronous operation must be performed, an
+ * <code>ItemPendingError</code> will be thrown. See the ItemPendingError docs
+ * as well as the collections documentation for more information on using the
+ * ItemPendingError.
+ *
+ * @return true if still in the list, false if current is now beforeFirst
+ *
+ * @see mx.collections.IViewCursor#current
+ * @see mx.collections.IViewCursor#moveNext
+ * @see mx.collections.errors.ItemPendingError
+ * @example
+ * <pre>
+ * var myArrayCollection:ICollectionView = new ArrayCollection(["Bobby", "Mark", "Trevor", "Jacey", "Tyler"]);
+ * var cursor:ICursor = myArrayCollection.createCursor();
+ * cursor.seek(CursorBookmark.last);
+ * while (!cursor.beforeFirst)
+ * {
+ * trace(current);
+ * cursor.movePrevious();
+ * }
+ * </pre>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+
+ public function movePrevious():Boolean
+ {
+ //the afterLast getter checks validity and also checks length > 0
+ if (beforeFirst)
+ {
+ return false;
+ }
+ // we can't set the index until we know that we can move there first
+ var tempIndex:int = afterLast ? view.length - 1 : currentIndex - 1;
+ if (tempIndex == -1)
+ {
+ tempIndex = BEFORE_FIRST_INDEX;
+ setCurrent(null);
+ }
+ else
+ {
+ setCurrent(ListCollectionView(view).getItemAt(tempIndex));
+ }
+ currentIndex = tempIndex;
+ return !beforeFirst;
+ }
+
+ /**
+ * Remove the current item and return it. If the cursor is
+ * <code>beforeFirst</code> or <code>afterLast</code> throw a
+ * CursorError.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function remove():Object
+ {
+ /*
+ if (beforeFirst || afterLast)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "invalidRemove");
+ throw new CursorError(message);
+ }
+ */
+ var oldIndex:int = currentIndex;
+ currentIndex++;
+ if (currentIndex >= view.length)
+ {
+ currentIndex = AFTER_LAST_INDEX;
+ setCurrent(null);
+ }
+ else
+ {
+ /*
+ try
+ {
+ */
+ setCurrent(ListCollectionView(view).getItemAt(currentIndex));
+ /*
+ }
+ catch(e:ItemPendingError)
+ {
+ setCurrent(null, false);
+ ListCollectionView(view).removeItemAt(oldIndex);
+ throw e;
+ }
+ */
+ }
+ var removed:Object = ListCollectionView(view).removeItemAt(oldIndex);
+ return removed;
+ }
+
+ /**
+ * Moves the cursor to a location at an offset from the specified
+ * bookmark.
+ * The offset can be negative in which case the cursor is positioned an
+ * offset number of items prior to the specified bookmark.
+ * If the associated collection is remote, and not all of the items have been
+ * cached locally this method will begin an asynchronous fetch from the
+ * remote collection.
+ *
+ * If the data is not local and an asynchronous operation must be performed, an
+ * <code>ItemPendingError</code> will be thrown. See the ItemPendingError docs
+ * as well as the collections documentation for more information on using the
+ * ItemPendingError.
+ *
+ *
+ * @param bookmark <code>CursorBookmark</code> reference to marker information that
+ * allows repositioning to a specific location.
+ * In addition to supplying a value returned from the <code>bookmark</code>
+ * property, there are three constant bookmark values that can be
+ * specified:
+ * <ul>
+ * <li><code>CursorBookmark.FIRST</code> - seek from
+ * the start (first element) of the collection</li>
+ * <li><code>CursorBookmark.CURRENT</code> - seek from
+ * the current position in the collection</li>
+ * <li><code>CursorBookmark.LAST</code> - seek from the
+ * end (last element) of the collection</li>
+ * </ul>
+ * @param offset indicates how far from the specified bookmark to seek.
+ * If the specified number is negative the cursor will attempt to
+ * move prior to the specified bookmark, if the offset specified is
+ * beyond the end points of the collection the cursor will be
+ * positioned off the end (beforeFirst or afterLast).
+ * @param prefetch indicates the intent to iterate in a specific direction once the
+ * seek operation completes, this reduces the number of required
+ * network round trips during a seek.
+ * If the iteration direction is known at the time of the request
+ * the appropriate amount of data can be returned ahead of the
+ * request to iterate it.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function seek(bookmark:CursorBookmark, offset:int = 0, prefetch:int = 0):void
+ {
+ checkValid();
+ if (view.length == 0)
+ {
+ currentIndex = AFTER_LAST_INDEX;
+ setCurrent(null, false);
+ return;
+ }
+
+ var newIndex:int = currentIndex;
+ if (bookmark == CursorBookmark.FIRST)
+ {
+ newIndex = 0;
+ }
+ else if (bookmark == CursorBookmark.LAST)
+ {
+ newIndex = view.length - 1;
+ }
+ else if (bookmark != CursorBookmark.CURRENT)
+ {
+ var message:String;
+ //try
+ //{
+ newIndex = ListCollectionView(view).getBookmarkIndex(bookmark);
+ if (newIndex < 0)
+ {
+ setCurrent(null);
+
+ /*
+ message = resourceManager.getString(
+ "collections", "bookmarkInvalid");
+ throw new CursorError(message);
+ */
+ }
+ /*
+ }
+ catch(bmError:CollectionViewError)
+ {
+ message = resourceManager.getString(
+ "collections", "bookmarkInvalid");
+ throw new CursorError(message);
+ }
+ */
+ }
+
+ newIndex += offset;
+
+ var newCurrent:Object = null;
+ if (newIndex >= view.length)
+ {
+ currentIndex = AFTER_LAST_INDEX;
+ }
+ else if (newIndex < 0)
+ {
+ currentIndex = BEFORE_FIRST_INDEX;
+ }
+ else
+ {
+ newCurrent = ListCollectionView(view).getItemAt(newIndex, prefetch);
+ currentIndex = newIndex;
+ }
+ setCurrent(newCurrent);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Internal methods
+ //
+ //--------------------------------------------------------------------------
+
+ private function checkValid():void
+ {
+ /*
+ if (invalid)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "invalidCursor");
+ throw new CursorError(message);
+ }
+ */
+ }
+
+ private function collectionEventHandler(event:CollectionEvent):void
+ {
+ switch (event.kind)
+ {
+ case CollectionEventKind.ADD:
+ if (event.location <= currentIndex)
+ {
+ currentIndex += event.items.length;
+ }
+ break;
+
+ case CollectionEventKind.REMOVE:
+ if (event.location < currentIndex)
+ {
+ currentIndex -= event.items.length;
+ }
+ else if (event.location == currentIndex)
+ {
+ if (currentIndex < view.length)
+ {
+ /*
+ try
+ {
+ */
+ setCurrent(ListCollectionView(view).getItemAt(currentIndex));
+ /*
+ }
+ catch(error:ItemPendingError)
+ {
+ setCurrent(null, false);
+ }
+ */
+ }
+ else // currentIndex == view.length
+ {
+ //we were removed! is this an error?
+ //should cursor move to now last item, view.length - 1??
+ currentIndex = AFTER_LAST_INDEX;
+ setCurrent(null); //dispatch the updated at least
+ }
+ }
+ break;
+
+ case CollectionEventKind.MOVE:
+ if (event.oldLocation == currentIndex)
+ {
+ currentIndex = event.location;
+ }
+ else
+ {
+ if (event.oldLocation < currentIndex)
+ {
+ currentIndex -= event.items.length;
+ }
+ if (event.location <= currentIndex)
+ {
+ currentIndex += event.items.length;
+ }
+ }
+ break;
+
+ case CollectionEventKind.REFRESH:
+ if (!(beforeFirst || afterLast))
+ {
+ try
+ {
+ currentIndex = ListCollectionView(view).getItemIndex(currentValue);
+ }
+ catch (e:SortError)
+ {
+ if (ListCollectionView(view).sort)
+ {
+ currentIndex = ListCollectionView(view).getLocalItemIndex(currentValue);
+ }
+ }
+ if (currentIndex == -1)
+ {
+ setCurrent(null);
+ }
+ }
+ break;
+
+ case CollectionEventKind.REPLACE:
+ if (event.location == currentIndex)
+ {
+ /*
+ try
+ {
+ */
+ setCurrent(ListCollectionView(view).getItemAt(currentIndex));
+ /*
+ }
+ catch(error:ItemPendingError)
+ {
+ setCurrent(null, false);
+ }
+ */
+ }
+ break;
+
+ case CollectionEventKind.RESET:
+ //just move to the beginning
+ currentIndex = BEFORE_FIRST_INDEX;
+ setCurrent(null);
+ break;
+ }
+ }
+
+ /**
+ * @private
+ */
+ private function setCurrent(value:Object, dispatch:Boolean = true):void
+ {
+ currentValue = value;
+
+ //if (dispatch)
+ // dispatchEvent(new FlexEvent(FlexEvent.CURSOR_UPDATE));
+ }
+}
+
+/**
+ * @private
+ * Encapsulates the positional aspects of a cursor within an ListCollectionView.
+ * Only the ListCollectionView should construct this.
+ */
+class ListCollectionViewBookmark extends CursorBookmark
+{
+ mx_internal var index:int;
+ mx_internal var view:ListCollectionView;
+ mx_internal var viewRevision:int;
+
+ /**
+ * @private
+ */
+ public function ListCollectionViewBookmark(value:Object,
+ view:ListCollectionView,
+ viewRevision:int,
+ index:int)
+ {
+ super(value);
+ this.view = view;
+ this.viewRevision = viewRevision;
+ this.index = index;
+ }
+
+ /**
+ * Gets the approximate index of the item represented by this bookmark
+ * in its view. If the item has been paged out, this method could throw an
+ * ItemPendingError.
+ *
+ * @return The index of the item. If the item is not in the current view,
+ * this method returns -1. This method also returns -1 if index-based location
+ * retrieval is not possible.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ override public function getViewIndex():int
+ {
+ return view.getBookmarkIndex(this);
+ }
}
\ No newline at end of file
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/Sort.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/Sort.as
index 4f6f812..1d9059d 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/Sort.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/Sort.as
@@ -1,227 +1,825 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-package mx.collections
-{
-
- /*
- import flash.events.Event;
- import flash.events.EventDispatcher; */
-
- import org.apache.royale.events.Event;
- import org.apache.royale.events.EventDispatcher;
-
- //import mx.collections.errors.SortError;
- import mx.core.mx_internal;
- /* import mx.resources.IResourceManager;
- import mx.resources.ResourceManager */;
- import mx.utils.ObjectUtil;
-
- use namespace mx_internal;
-
- [DefaultProperty("fields")]
-//[ResourceBundle("collections")]
-/* [Alternative(replacement="spark.collections.Sort", since="4.5")]
- */
-/**
- * Provides the sorting information required to establish a sort on an
- * existing view (<code>ICollectionView</code> interface or class that
- * implements the interface). After you assign a <code>Sort</code> instance to the view's
- * <code>sort</code> property, you must call the view's
- * <code>refresh()</code> method to apply the sort criteria.
- *
- * <p>Typically the sort is defined for collections of complex items, that is
- * collections in which the sort is performed on one or more properties of
- * the objects in the collection.
- * The following example shows this use:</p>
- * <pre><code>
- * var col:ICollectionView = new ArrayCollection();
- * // In the real world, the collection would have more than one item.
- * col.addItem({first:"Anders", last:"Dickerson"});
- *
- * // Create the Sort instance.
- * var sort:ISort = new Sort();
- *
- * // Set the sort field; sort on the last name first, first name second.
- * // Both fields are case-insensitive.
- * sort.fields = [new SortField("last",true), new SortField("first",true)];
- * // Assign the Sort object to the view.
- * col.sort = sort;
- *
- * // Apply the sort to the collection.
- * col.refresh();
- * </code></pre>
- *
- * <p>There are situations in which the collection contains simple items,
- * like <code>String</code>, <code>Date</code>, <code>Boolean</code>, etc.
- * In this case, apply the sort to the simple type directly.
- * When constructing a sort for simple items, use a single sort field,
- * and specify a <code>null</code> <code>name</code> (first) parameter
- * in the SortField object constructor.
- * For example:
- * <pre><code>
- * var col:ICollectionView = new ArrayCollection();
- * col.addItem("California");
- * col.addItem("Arizona");
- * var sort:Sort = new Sort();
- *
- * // There is only one sort field, so use a <code>null</code>
- * // first parameter.
- * sort.fields = [new SortField(null, true)];
- * col.sort = sort;
- * col.refresh();
- * </code></pre>
- * </p>
- *
- * <p>The Flex implementations of the <code>ICollectionView</code> interface
- * retrieve all items from a remote location before executing a sort.
- * If you use paging with a sorted list, apply the sort to the remote
- * collection before you retrieve the data.
- * </p>
- *
- * <p>By default this Sort class does not provide correct language specific
- * sorting for strings. For this type of sorting please see the
- * <code>spark.collections.Sort</code> and
- * <code>spark.collections.SortField</code> classes.</p>
- *
- * Note: to prevent problems like
- * <a href="https://issues.apache.org/jira/browse/FLEX-34853">FLEX-34853</a>
- * it is recommended to use SortField
- * instances as immutable objects (by not changing their state).
- *
- * @mxml
- *
- * <p>The <code><mx:Sort></code> tag has the following attributes:</p>
- *
- * <pre>
- * <mx:Sort
- * <b>Properties</b>
- * compareFunction="<em>Internal compare function</em>"
- * fields="null"
- * unique="false | true"
- * />
- * </pre>
- *
- * <p>In case items have inconsistent data types or items have complex data
- * types, the use of the default built-in compare functions is not recommended.
- * Inconsistent sorting results may occur in such cases. To avoid such problem,
- * provide a custom compare function and/or make the item types consistent.</p>
- *
- * <p>Just like any other <code>AdvancedStyleClient</code>-based classes,
- * the <code>Sort</code> and <code>SortField</code> classes do not have a
- * parent-child relationship in terms of event handling. Locale changes in a
- * <code>Sort</code> instance are not dispatched to its <code>SortField</code>
- * instances automatically. The only exceptional case is the internal default
- * <code>SortField</code> instance used when no explicit fields are provided.
- * In this case, the internal default <code>SortField</code> instance follows
- * the locale style that the owner <code>Sort</code> instance has.</p>
- *
- * @see mx.collections.ICollectionView
- * @see ISortField
- * @see spark.collections.Sort
- * @see spark.collections.SortField
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- * @royalesuppresspublicvarwarning
- */
-public class Sort extends EventDispatcher implements ISort
-{
-
- //--------------------------------------------------------------------------
- //
- // Constructor
- //
- //--------------------------------------------------------------------------
-
- /**
- * Constructor.
- *
- * <p>Creates a new Sort with no fields set and no custom comparator.</p>
- *
- * @param fields An <code>Array</code> of <code>ISortField</code> objects that
- * specifies the fields to compare.
- * @param customCompareFunction Use a custom function to compare the
- * objects in the collection to which this sort will be applied.
- * @param unique Indicates if the sort should be unique.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- public function Sort(fields:Array = null, customCompareFunction:Function = null, unique:Boolean = false)
- {
- super();
-
- this.fields = fields;
-
- }
-
- //--------------------------------------------------------------------------
- //
- // Variables
- //
- //--------------------------------------------------------------------------
-
-
- //----------------------------------
- // fields
- //----------------------------------
-
- /**
- * @private
- * Storage for the fields property.
- */
- private var _fields:Array;
-
- [Inspectable(category="General", arrayType="mx.collections.ISortField")]
- [Bindable("fieldsChanged")]
-
- /**
- * @inheritDoc
- *
- * @default null
- *
- * @see SortField
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- public function get fields():Array
- {
- return _fields;
- }
-
- /**
- * @private
- */
- public function set fields(value:Array):void
- {
- _fields = value;
-
- dispatchEvent(new Event("fieldsChanged"));
- }
-
-}
-}
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.collections
+{
+
+ import org.apache.royale.events.Event;
+ import org.apache.royale.events.EventDispatcher;
+
+ import mx.collections.errors.SortError;
+ import mx.core.mx_internal;
+ //import mx.resources.IResourceManager;
+ //import mx.resources.ResourceManager;
+ //import mx.utils.ObjectUtil;
+
+ use namespace mx_internal;
+
+ [DefaultProperty("fields")]
+//[ResourceBundle("collections")]
+//[Alternative(replacement="spark.collections.Sort", since="4.5")]
+
+/**
+ * Provides the sorting information required to establish a sort on an
+ * existing view (<code>ICollectionView</code> interface or class that
+ * implements the interface). After you assign a <code>Sort</code> instance to the view's
+ * <code>sort</code> property, you must call the view's
+ * <code>refresh()</code> method to apply the sort criteria.
+ *
+ * <p>Typically the sort is defined for collections of complex items, that is
+ * collections in which the sort is performed on one or more properties of
+ * the objects in the collection.
+ * The following example shows this use:</p>
+ * <pre><code>
+ * var col:ICollectionView = new ArrayCollection();
+ * // In the real world, the collection would have more than one item.
+ * col.addItem({first:"Anders", last:"Dickerson"});
+ *
+ * // Create the Sort instance.
+ * var sort:ISort = new Sort();
+ *
+ * // Set the sort field; sort on the last name first, first name second.
+ * // Both fields are case-insensitive.
+ * sort.fields = [new SortField("last",true), new SortField("first",true)];
+ * // Assign the Sort object to the view.
+ * col.sort = sort;
+ *
+ * // Apply the sort to the collection.
+ * col.refresh();
+ * </code></pre>
+ *
+ * <p>There are situations in which the collection contains simple items,
+ * like <code>String</code>, <code>Date</code>, <code>Boolean</code>, etc.
+ * In this case, apply the sort to the simple type directly.
+ * When constructing a sort for simple items, use a single sort field,
+ * and specify a <code>null</code> <code>name</code> (first) parameter
+ * in the SortField object constructor.
+ * For example:
+ * <pre><code>
+ * var col:ICollectionView = new ArrayCollection();
+ * col.addItem("California");
+ * col.addItem("Arizona");
+ * var sort:Sort = new Sort();
+ *
+ * // There is only one sort field, so use a <code>null</code>
+ * // first parameter.
+ * sort.fields = [new SortField(null, true)];
+ * col.sort = sort;
+ * col.refresh();
+ * </code></pre>
+ * </p>
+ *
+ * <p>The Flex implementations of the <code>ICollectionView</code> interface
+ * retrieve all items from a remote location before executing a sort.
+ * If you use paging with a sorted list, apply the sort to the remote
+ * collection before you retrieve the data.
+ * </p>
+ *
+ * <p>By default this Sort class does not provide correct language specific
+ * sorting for strings. For this type of sorting please see the
+ * <code>spark.collections.Sort</code> and
+ * <code>spark.collections.SortField</code> classes.</p>
+ *
+ * Note: to prevent problems like
+ * <a href="https://issues.apache.org/jira/browse/FLEX-34853">FLEX-34853</a>
+ * it is recommended to use SortField
+ * instances as immutable objects (by not changing their state).
+ *
+ * @mxml
+ *
+ * <p>The <code><mx:Sort></code> tag has the following attributes:</p>
+ *
+ * <pre>
+ * <mx:Sort
+ * <b>Properties</b>
+ * compareFunction="<em>Internal compare function</em>"
+ * fields="null"
+ * unique="false | true"
+ * />
+ * </pre>
+ *
+ * <p>In case items have inconsistent data types or items have complex data
+ * types, the use of the default built-in compare functions is not recommended.
+ * Inconsistent sorting results may occur in such cases. To avoid such problem,
+ * provide a custom compare function and/or make the item types consistent.</p>
+ *
+ * <p>Just like any other <code>AdvancedStyleClient</code>-based classes,
+ * the <code>Sort</code> and <code>SortField</code> classes do not have a
+ * parent-child relationship in terms of event handling. Locale changes in a
+ * <code>Sort</code> instance are not dispatched to its <code>SortField</code>
+ * instances automatically. The only exceptional case is the internal default
+ * <code>SortField</code> instance used when no explicit fields are provided.
+ * In this case, the internal default <code>SortField</code> instance follows
+ * the locale style that the owner <code>Sort</code> instance has.</p>
+ *
+ * @see mx.collections.ICollectionView
+ * @see ISortField
+ * @see spark.collections.Sort
+ * @see spark.collections.SortField
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class Sort extends EventDispatcher implements ISort
+{
+// include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * When executing a find return the index any matching item.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const ANY_INDEX_MODE:String = "any";
+
+ /**
+ * When executing a find return the index for the first matching item.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const FIRST_INDEX_MODE:String = "first";
+
+ /**
+ * When executing a find return the index for the last matching item.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const LAST_INDEX_MODE:String = "last";
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * <p>Creates a new Sort with no fields set and no custom comparator.</p>
+ *
+ * @param fields An <code>Array</code> of <code>ISortField</code> objects that
+ * specifies the fields to compare.
+ * @param customCompareFunction Use a custom function to compare the
+ * objects in the collection to which this sort will be applied.
+ * @param unique Indicates if the sort should be unique.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function Sort(fields:Array = null, customCompareFunction:Function = null, unique:Boolean = false)
+ {
+ super();
+
+ this.fields = fields;
+ this.compareFunction = customCompareFunction;
+ this.unique = unique;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Used for accessing localized Error messages.
+ */
+ //private var resourceManager:IResourceManager =
+ // ResourceManager.getInstance();
+
+ /**
+ * @private
+ * True if we should attempt to use Array.sortOn when possible.
+ */
+ mx_internal var useSortOn:Boolean = true;
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // compareFunction
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the compareFunction property.
+ */
+ private var _compareFunction:Function;
+
+ /**
+ * @private
+ */
+ private var usingCustomCompareFunction:Boolean;
+
+ [Inspectable(category="General")]
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get compareFunction():Function
+ {
+ return usingCustomCompareFunction ? _compareFunction : internalCompare;
+ }
+
+ /**
+ * @private
+ */
+ public function set compareFunction(value:Function):void
+ {
+ _compareFunction = value;
+ usingCustomCompareFunction = _compareFunction != null;
+ }
+
+ //----------------------------------
+ // fields
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the fields property.
+ */
+ private var _fields:Array;
+
+ [Inspectable(category="General", arrayType="mx.collections.ISortField")]
+ [Bindable("fieldsChanged")]
+
+ /**
+ * @inheritDoc
+ *
+ * @default null
+ *
+ * @see SortField
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get fields():Array
+ {
+ return _fields;
+ }
+
+ /**
+ * @private
+ */
+ public function set fields(value:Array):void
+ {
+ _fields = value;
+
+ dispatchEvent(new Event("fieldsChanged"));
+ }
+
+ //----------------------------------
+ // unique
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the unique property.
+ */
+ private var _unique:Boolean;
+
+ [Inspectable(category="General")]
+
+ /**
+ * @inheritDoc
+ *
+ * @default false
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get unique():Boolean
+ {
+ return _unique;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function set unique(value:Boolean):void
+ {
+ _unique = value;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * A pretty printer for Sort that lists the sort fields and their
+ * options.
+ override public function toString():String
+ {
+ return ObjectUtil.toString(this);
+ }
+ */
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function findItem(items:Array,
+ values:Object,
+ mode:String,
+ returnInsertionIndex:Boolean = false,
+ compareFunction:Function = null):int
+ {
+ var compareForFind:Function;
+ var fieldsForCompare:Array;
+ var message:String;
+
+ /*
+ if (!items)
+ {
+ message = resourceManager.getString(
+ "collections", "noItems");
+ throw new SortError(message);
+ }
+ else*/ if (items.length == 0)
+ {
+ return returnInsertionIndex ? 1 : -1;
+ }
+
+ if (compareFunction == null)
+ {
+ compareForFind = this.compareFunction;
+ // configure the search criteria
+ if (values && fields && fields.length > 0)
+ {
+ fieldsForCompare = [];
+ //build up the fields we can compare, if we skip a field in the
+ //middle throw an error. It is ok to not have all the fields though
+ var field:ISortField;
+ var hadPreviousFieldName:Boolean = true;
+ for (var i:int = 0; i < fields.length; i++)
+ {
+ field = fields[i] as ISortField;
+ if (field.name)
+ {
+ if (field.objectHasSortField(values))
+ {
+ if (!hadPreviousFieldName)
+ {
+ message = /*resourceManager.getString(
+ "collections", */"findCondition"/*, [field.name])*/;
+ throw new SortError(message);
+ }
+ else
+ {
+ fieldsForCompare.push(field.name);
+ }
+ }
+ else
+ {
+ hadPreviousFieldName = false;
+ }
+ }
+ else
+ {
+ //this is ok because sometimes a SortField might
+ //have a custom comparator
+ fieldsForCompare.push(null);
+ }
+ }
+ if (fieldsForCompare.length == 0)
+ {
+ message = /*resourceManager.getString(
+ "collections", */"findRestriction"/*)*/;
+ throw new SortError(message);
+ }
+ else
+ {
+ try
+ {
+ initSortFields(items[0]);
+ }
+ catch(initSortError:SortError)
+ {
+ //oh well, use the default comparators...
+ }
+ }
+ }
+ }
+ else
+ {
+ compareForFind = compareFunction;
+ }
+
+ // let's begin searching
+ var found:Boolean = false;
+ var objFound:Boolean = false;
+ var index:int = 0;
+ var lowerBound:int = 0;
+ var upperBound:int = items.length -1;
+ var obj:Object = null;
+ var direction:int = 1;
+ while(!objFound && (lowerBound <= upperBound))
+ {
+ index = Math.round((lowerBound+ upperBound)/2);
+ obj = items[index];
+ //if we were given fields for comparison use that method, but
+ //if not the comparator may be for SortField in which case
+ //it'd be an error to pass a 3rd parameter
+ direction = fieldsForCompare
+ ? compareForFind(values, obj, fieldsForCompare)
+ : compareForFind(values, obj);
+
+ switch(direction)
+ {
+ case -1:
+ upperBound = index -1;
+ break;
+
+ case 0:
+ objFound = true;
+ switch(mode)
+ {
+ case ANY_INDEX_MODE:
+ found = true;
+ break;
+
+ case FIRST_INDEX_MODE:
+ found = (index == lowerBound);
+ // start looking towards bof
+ var objIndex:int = index - 1;
+ var match:Boolean = true;
+ while(match && !found && (objIndex >= lowerBound))
+ {
+ obj = items[objIndex];
+ var prevCompare:int = fieldsForCompare
+ ? compareForFind(values, obj, fieldsForCompare)
+ : compareForFind(values, obj);
+ match = (prevCompare == 0);
+ if (!match || (match && (objIndex == lowerBound)))
+ {
+ found= true;
+ index = objIndex + (match ? 0 : 1);
+ } // if match
+ objIndex--;
+ } // while
+ break;
+
+ case LAST_INDEX_MODE:
+ // if we where already at the edge case then we already found the last value
+ found = (index == upperBound);
+ // start looking towards eof
+ objIndex = index + 1;
+ match = true;
+ while(match && !found && (objIndex <= upperBound))
+ {
+ obj = items[objIndex];
+ var nextCompare:int = fieldsForCompare
+ ? compareForFind(values, obj, fieldsForCompare)
+ : compareForFind(values, obj);
+ match = (nextCompare == 0);
+ if (!match || (match && (objIndex == upperBound)))
+ {
+ found= true;
+ index = objIndex - (match ? 0 : 1);
+ } // if match
+ objIndex++;
+ } // while
+ break;
+ default:
+ {
+ message = /*resourceManager.getString(
+ "collections", */"unknownMode"/*)*/;
+ throw new SortError(message);
+ }
+ } // switch
+ break;
+
+ case 1:
+ lowerBound = index +1;
+ break;
+ } // switch
+ } // while
+ if (!found && !returnInsertionIndex)
+ {
+ return -1;
+ }
+ else
+ {
+ return (direction > 0) ? index + 1 : index;
+ }
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function propertyAffectsSort(property:String):Boolean
+ {
+ if (usingCustomCompareFunction || !fields)
+ return true;
+
+ for (var i:int = 0; i < fields.length; i++)
+ {
+ var field:ISortField = fields[i];
+ if (field.name == property || field.usingCustomCompareFunction)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function reverse():void
+ {
+ if (fields)
+ {
+ for (var i:int = 0; i < fields.length; i++)
+ {
+ ISortField(fields[i]).reverse();
+ }
+ }
+ noFieldsDescending = !noFieldsDescending;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function sort(items:Array):void
+ {
+ if (!items || items.length <= 1)
+ {
+ return;
+ }
+
+ if (usingCustomCompareFunction)
+ {
+ // bug 185872
+ // the Sort.internalCompare function knows to use Sort._fields; that same logic
+ // needs to be part of calling a custom compareFunction. Of course, a user shouldn't
+ // be doing this -- so I wrap calls to compareFunction with _fields as the last parameter
+ const fixedCompareFunction:Function =
+ function (a:Object, b:Object):int
+ {
+ // append our fields to the call, since items.sort() won't
+ return compareFunction(a, b, _fields);
+ };
+
+ var message:String;
+
+ if (unique)
+ {
+ var uniqueRet1:Object = items.sort(fixedCompareFunction, Array.UNIQUESORT);
+ if (uniqueRet1 == 0)
+ {
+ message = /*resourceManager.getString(
+ "collections", */"nonUnique"/*)*/;
+ throw new SortError(message);
+ }
+ }
+ else
+ {
+ items.sort(fixedCompareFunction);
+ }
+ }
+ else
+ {
+ if (fields && fields.length > 0)
+ {
+ //doing the init value each time may be a little inefficient
+ //but allows for the data to change and the comparators
+ //to update correctly
+ //the sortArgs is an object that if non-null means
+ //we can use Array.sortOn which will be much faster
+ //than going through internalCompare. However
+ //if the Sort is supposed to be unique and fields.length > 1
+ //we cannot use sortOn since it only tests uniqueness
+ //on the first field
+ var sortArgs:Object = initSortFields(items[0], true);
+
+ if (unique)
+ {
+ var uniqueRet2:Object;
+ if (useSortOn && sortArgs && fields.length == 1)
+ {
+ uniqueRet2 = items.sortOn(sortArgs.fields[0], sortArgs.options[0] | Array.UNIQUESORT);
+ }
+ else
+ {
+ uniqueRet2 = items.sort(internalCompare, Array.UNIQUESORT);
+ }
+ if (uniqueRet2 == 0)
+ {
+ message = /*resourceManager.getString(
+ "collections", */"nonUnique"/*)*/;
+ throw new SortError(message);
+ }
+ }
+ else
+ {
+ if (useSortOn && sortArgs)
+ {
+ items.sortOn(sortArgs.fields, sortArgs.options);
+ }
+ else
+ {
+ items.sort(internalCompare);
+ }
+ }
+ }
+ else
+ {
+ items.sort(internalCompare);
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Private Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Make sure all SortFields are ready to execute their comparators.
+ */
+ private function initSortFields(item:Object, buildArraySortArgs:Boolean = false):Object
+ {
+ var arraySortArgs:Object = null;
+ var i:int;
+ for (i = 0; i<fields.length; i++)
+ {
+ ISortField(fields[i]).initializeDefaultCompareFunction(item);
+ }
+ if (buildArraySortArgs)
+ {
+ arraySortArgs = {fields: [], options: []};
+ for (i = 0; i<fields.length; i++)
+ {
+ var field:ISortField = fields[i];
+ var options:int = field.arraySortOnOptions;
+ if (options == -1)
+ {
+ return null;
+ }
+ else
+ {
+ arraySortArgs.fields.push(field.name);
+ arraySortArgs.options.push(options);
+ }
+ }
+
+ }
+ return arraySortArgs;
+ }
+
+ /**
+ * @private
+ * Compares the values specified based on the sort field options specified
+ * for this sort. The fields parameter is really just used to get the
+ * number of fields to check. We don't look at the actual values
+ * to see if they match the actual sort.
+ */
+ private function internalCompare(a:Object, b:Object, fields:Array = null):int
+ {
+ var result:int = 0;
+ if (!_fields)
+ {
+ result = noFieldsCompare(a, b);
+ }
+ else
+ {
+ var i:int = 0;
+ var len:int = fields ? fields.length : _fields.length;
+ while (result == 0 && (i < len))
+ {
+ var sf:ISortField = ISortField(_fields[i]);
+ result = sf.compareFunction(a, b);
+ if (sf.descending)
+ result *= -1;
+ i++;
+ }
+ }
+
+ return result;
+ }
+
+ private var defaultEmptyField:ISortField;
+ private var noFieldsDescending:Boolean = false;
+
+ /**
+ * If the sort does not have any sort fields nor a custom comparator
+ * just use an empty SortField object and have it use its default
+ * logic.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function noFieldsCompare(a:Object, b:Object, fields:Array = null):int
+ {
+ if (!defaultEmptyField)
+ {
+ defaultEmptyField = createEmptySortField();
+ try
+ {
+ defaultEmptyField.initializeDefaultCompareFunction(a);
+ }
+ catch(e:SortError)
+ {
+ //this error message isn't as useful in this case so replace
+ var message:String = /*resourceManager.getString(
+ "collections", */"noComparator"/*, [ a ])*/;
+ throw new SortError(message);
+ }
+ }
+
+ var result:int = defaultEmptyField.compareFunction(a, b);
+
+ if (noFieldsDescending)
+ {
+ result *= -1;
+ }
+
+ return result;
+ }
+
+ protected function createEmptySortField():ISortField
+ {
+ return new SortField();
+ }
+}
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/SortField.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/SortField.as
index ad1e419..402ad69 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/SortField.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/SortField.as
@@ -1,855 +1,848 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-package mx.collections
-{
-
-
-/*
- import flash.events.Event;
- import flash.events.EventDispatcher; */
-
- import org.apache.royale.events.Event;
- import org.apache.royale.events.EventDispatcher;
-
- // import mx.collections.errors.SortError;
- import mx.core.mx_internal;
-/* import mx.resources.IResourceManager; */ //commented
-
- /* import mx.resources.ResourceManager; */ //commented
- import mx.utils.ObjectUtil;
-
- [ResourceBundle("collections")]
-/* [Alternative(replacement="spark.collections.SortField", since="4.5")]
- */
-/**
- * Provides the sorting information required to establish a sort on a field
- * or property in a collection view.
- *
- * The SortField class is meant to be used with the Sort class.
- *
- * Typically the sort is defined for collections of complex items, that is
- * items in which the sort is performed on properties of those objects.
- * As in the following example:
- *
- * <pre><code>
- * var col:ICollectionView = new ArrayCollection();
- * col.addItem({first:"Anders", last:"Dickerson"});
- * var sort:Sort = new Sort();
- * sort.fields = [new SortField("first", true)];
- * col.sort = sort;
- * </code></pre>
- *
- * There are situations in which the collection contains simple items, like
- * <code>String</code>, <code>Date</code>, <code>Boolean</code>, etc.
- * In this case, sorting should be applied to the simple type directly.
- * When constructing a sort for this situation only a single sort field is
- * required and should not have a <code>name</code> specified.
- * For example:
- *
- * <pre><code>
- * var col:ICollectionView = new ArrayCollection();
- * col.addItem("California");
- * col.addItem("Arizona");
- * var sort:Sort = new Sort();
- * sort.fields = [new SortField(null, true)];
- * col.sort = sort;
- * </code></pre>
- *
- * <p>By default the comparison provided by the SortField class does
- * not provide correct language specific
- * sorting for strings. For this type of sorting please see the
- * <code>spark.collections.Sort</code> and
- * <code>spark.collections.SortField</code> classes.</p>
- *
- * Note: to prevent problems like
- * <a href="https://issues.apache.org/jira/browse/FLEX-34853">FLEX-34853</a>
- * it is recommended to use SortField
- * instances as immutable objects (by not changing their state).
- *
- * @mxml
- *
- * <p>The <code><mx:SortField></code> tag has the following attributes:</p>
- *
- * <pre>
- * <mx:SortField
- * <b>Properties</b>
- * caseInsensitive="false"
- * compareFunction="<em>Internal compare function</em>"
- * descending="false"
- * name="null"
- * numeric="null"
- * />
- * </pre>
- *
- * @see mx.collections.ICollectionView
- * @see mx.collections.Sort
- * @see spark.collections.Sort
- * @see spark.collections.SortField
-
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
-public class SortField extends EventDispatcher implements ISortField
-{
- /* include "../core/Version.as"; */
-
- //--------------------------------------------------------------------------
- //
- // Constructor
- //
- //--------------------------------------------------------------------------
-
- /**
- * Constructor.
- *
- * @param name The name of the property that this field uses for
- * comparison.
- * If the object is a simple type, pass <code>null</code>.
- * @param caseInsensitive When sorting strings, tells the comparator
- * whether to ignore the case of the values.
- * @param descending Tells the comparator whether to arrange items in
- * descending order.
- * @param numeric Tells the comparator whether to compare sort items as
- * numbers, instead of alphabetically.
- * @param sortCompareType Gives an indication to SortField which of the
- * default compare functions to use.
- * @param customCompareFunction Use a custom function to compare the
- * objects based on this SortField.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- public function SortField(name:String = null,
- caseInsensitive:Boolean = false,
- descending:Boolean = false,
- numeric:Object = null,
- sortCompareType:String = null,
- customCompareFunction:Function = null)
- {
- super();
-
- _name = name;
- _caseInsensitive = caseInsensitive;
- // _descending = descending;
- _numeric = numeric;
- // _sortCompareType = sortCompareType;
-
- /* if(customCompareFunction != null)
- {
- compareFunction = customCompareFunction;
- }
- else if (updateSortCompareType() == false)
- {
- _compareFunction = stringCompare;
- } */
- }
-
- //--------------------------------------------------------------------------
- //
- // Variables
- //
- //--------------------------------------------------------------------------
-
- /**
- * @private
- * Used for accessing localized Error messages.
- */
- /* private var resourceManager:IResourceManager =
- ResourceManager.getInstance(); */
-
- //--------------------------------------------------------------------------
- //
- // Properties
- //
- //--------------------------------------------------------------------------
-
- //---------------------------------
- // arraySortOnOptions
- //---------------------------------
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- /* public function get arraySortOnOptions():int
- {
- if (usingCustomCompareFunction
- || name == null
- || _compareFunction == xmlCompare
- || _compareFunction == dateCompare)
- {
- return -1;
- }
- var options:int = 0;
- if (caseInsensitive) options |= Array.CASEINSENSITIVE;
- if (descending) options |= Array.DESCENDING;
- if (numeric == true || _compareFunction == numericCompare) options |= Array.NUMERIC;
- return options;
- } */
-
- //---------------------------------
- // caseInsensitive
- //---------------------------------
-
- /**
- * @private
- * Storage for the caseInsensitive property.
- */
- private var _caseInsensitive:Boolean;
-
- [Inspectable(category="General")]
- [Bindable("caseInsensitiveChanged")]
-
- /**
- * Specifies whether the sort for this field should be case insensitive.
- *
- * @default false
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- public function get caseInsensitive():Boolean
- {
- return _caseInsensitive;
- }
-
- /**
- * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
- * argument instead.
- */
- mx_internal function setCaseInsensitive(value:Boolean):void
- {
- if (value != _caseInsensitive)
- {
- _caseInsensitive = value;
- dispatchEvent(new Event("caseInsensitiveChanged"));
- }
- }
-
- //---------------------------------
- // compareFunction
- //---------------------------------
-
- /**
- * @private
- * Storage for the compareFunction property.
- */
- /* private var _compareFunction:Function;
-
- [Inspectable(category="General")] */
-
- /**
- * The function that compares two items during a sort of items for the
- * associated collection. If you specify a <code>compareFunction</code>
- * property in an <code>ISort</code> object, Flex ignores any
- * <code>compareFunction</code> properties of the ISort's
- * <code>SortField</code> objects.
- *
- * <p>The compare function must have the following signature:</p>
- *
- * <p><code>function myCompare(a:Object, b:Object):int</code></p>
- *
- * <p>This function must return the following values:</p>
- *
- * <ul>
- * <li>-1, if the <code>Object a</code> should appear before the
- * <code>Object b</code> in the sorted sequence</li>
- * <li>0, if the <code>Object a</code> equals the
- * <code>Object b</code></li>
- * <li>1, if the <code>Object a</code> should appear after the
- * <code>Object b</code> in the sorted sequence</li>
- * </ul>
- *
- * <p>The default value is an internal compare function that can perform
- * a string, numeric, or date comparison in ascending or descending order,
- * with case-sensitive or case-insensitive string comparisons.
- * Specify your own function only if you need a need a custom comparison
- * algorithm. This is normally only the case if a calculated field is
- * used in a display.</p>
- *
- * Note if you need language-specific sorting then consider using the
- * <code>spark.collections.SortField</code> class.
- *
- * @see spark.collections.SortField
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- /* public function get compareFunction():Function
- {
- return _compareFunction;
- } */
-
- /**
- * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
- * argument instead.
- */
- /* public function set compareFunction(c:Function):void
- {
- _compareFunction = c;
- _usingCustomCompareFunction = (c != null);
- } */
-
- //---------------------------------
- // descending
- //---------------------------------
-
- /**
- * @private
- * Storage for the descending property.
- */
- /* private var _descending:Boolean;
-
- [Inspectable(category="General")]
- [Bindable("descendingChanged")] */
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- /* public function get descending():Boolean
- {
- return _descending;
- } */
-
- /**
- * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
- * argument instead.
- */
- /* public function set descending(value:Boolean):void
- {
- if (_descending != value)
- {
- _descending = value;
- dispatchEvent(new Event("descendingChanged"));
- }
- } */
-
- //---------------------------------
- // name
- //---------------------------------
-
- /**
- * @private
- * Storage for the name property.
- */
- private var _name:String;
-
- [Inspectable(category="General")]
- [Bindable("nameChanged")]
-
- /**
- * @inheritDoc
- *
- * @default null
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- public function get name():String
- {
- return _name;
- }
-
- /**
- * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
- * argument instead.
- */
- public function set name(n:String):void
- {
- _name = n;
- dispatchEvent(new Event("nameChanged"));
- }
-
- //---------------------------------
- // numeric
- //---------------------------------
-
- /**
- * @private
- * Storage for the numeric property.
- */
- private var _numeric:Object;
-
- [Inspectable(category="General")]
- [Bindable("numericChanged")]
-
- /**
- * @inheritDoc
- *
- * @default null
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- public function get numeric():Object
- {
- return _numeric;
- }
-
- /**
- * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
- * argument instead.
- */
- public function set numeric(value:Object):void
- {
- if (_numeric != value)
- {
- _numeric = value;
- dispatchEvent(new Event("numericChanged"));
- }
- }
-
-
- //---------------------------------
- // sortCompareType
- //---------------------------------
-
- /**
- * @private
- */
- /* private var _sortCompareType:String = null; */
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 11.8
- * @playerversion AIR 3.8
- * @productversion Royale 0.9.4
- */
- /* [Bindable("sortCompareTypeChanged")]
- public function get sortCompareType():String
- {
- return _sortCompareType;
- } */
-
- /**
- * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
- * argument instead.
- */
- /* public function set sortCompareType(value:String):void
- {
- if (_sortCompareType != value)
- {
- _sortCompareType = value;
- dispatchEvent(new Event("sortCompareTypeChanged"));
- }
-
- updateSortCompareType();
- } */
-
-
- //---------------------------------
- // usingCustomCompareFunction
- //---------------------------------
-
- /* private var _usingCustomCompareFunction:Boolean; */
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- /* public function get usingCustomCompareFunction():Boolean
- {
- return _usingCustomCompareFunction;
- } */
-
- //--------------------------------------------------------------------------
- //
- // Overridden Methods
- //
- //--------------------------------------------------------------------------
-
- /**
- * @private
- * A pretty printer for SortField that lists the sort fields and their
- * options.
- */
- /* override public function toString():String
- {
- return "";
- } */
-
- //--------------------------------------------------------------------------
- //
- // Methods
- //
- //--------------------------------------------------------------------------
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- /* public function initializeDefaultCompareFunction(obj:Object):void
- {
- // if the compare function is not already set then we can set it
- if (!usingCustomCompareFunction)
- {
- if (_sortCompareType)
- {
- //Attempt to set the compare function based on the sortCompareType
- if (updateSortCompareType() == true)
- {
- return;
- }
- }
-
- if (numeric == true)
- _compareFunction = numericCompare;
- else if (caseInsensitive || numeric == false)
- _compareFunction = stringCompare;
- else
- {
- // we need to introspect the data a little bit
- var value:Object;
- if (_name)
- {
- value = getSortFieldValue(obj);
- }
- //this needs to be an == null check because !value will return true
- //where value == 0 or value == false
- if (value == null)
- {
- value = obj;
- }
-
- var typ:String = typeof(value);
- switch (typ)
- {
- case "string":
- _compareFunction = stringCompare;
- break;
- case "object":
- if (value is Date)
- {
- _compareFunction = dateCompare;
- }
- else
- {
- _compareFunction = stringCompare;
- var test:String;
- try
- {
- test = value.toString();
- }
- catch(error2:Error)
- {
- }
- if (!test || test == "[object Object]")
- {
- _compareFunction = nullCompare;
- }
- }
- break;
- case "xml":
- _compareFunction = xmlCompare;
- break;
- case "boolean":
- case "number":
- _compareFunction = numericCompare;
- break;
- }
- } // else
- } // if
- } */
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- /* public function reverse():void
- {
- descending = !descending;
- } */
-
-
- /**
- * @inheritDoc
- *
- * @langversion 3.0
- * @playerversion Flash 11.8
- * @playerversion AIR 3.8
- * @productversion Royale 0.9.4
- */
- /* public function updateSortCompareType():Boolean
- {
- if (!_sortCompareType)
- {
- return false;
- }
-
-
- //Lookup the sortCompareType by its SortFieldCompareTypes value and set the associated compare method.
- switch(_sortCompareType)
- {
- case SortFieldCompareTypes.DATE:
- {
- _compareFunction = dateCompare;
-
- return true;
- }
-
- case SortFieldCompareTypes.NULL:
- {
- _compareFunction = nullCompare;
-
- return true;
- }
-
- case SortFieldCompareTypes.NUMERIC:
- {
- _compareFunction = numericCompare;
-
- return true;
- }
-
- case SortFieldCompareTypes.STRING:
- {
- _compareFunction = stringCompare;
-
- return true;
- }
-
- case SortFieldCompareTypes.XML:
- {
- _compareFunction = xmlCompare;
-
- return true;
- }
- }
-
-
- return false;
- }
-
-
- public function objectHasSortField(object:Object):Boolean
- {
- return getSortFieldValue(object) !== undefined;
- } */
-
-
- //--------------------------------------------------------------------------
- //
- // Protected Methods
- //
- //--------------------------------------------------------------------------
-
- /* protected function getSortFieldValue(obj:Object):*
- {
- var result:* = undefined;
-
- try
- {
- result = obj[_name];
- }
- catch(error:Error)
- {
- }
-
- return result;
- } */
-
- //--------------------------------------------------------------------------
- //
- // Private Methods
- //
- //--------------------------------------------------------------------------
-
- /* private function nullCompare(a:Object, b:Object):int
- {
- var left:Object;
- var right:Object;
-
- var found:Boolean = false;
-
- // return 0 (ie equal) if both are null
- if (a == null && b == null)
- {
- return 0;
- }
-
- // we need to introspect the data a little bit
- if (_name)
- {
- left = getSortFieldValue(a);
- right = getSortFieldValue(b);
- }
-
- // return 0 (ie equal) if both are null
- if (left == null && right == null)
- return 0;
-
- if (left == null && !_name)
- left = a;
-
- if (right == null && !_name)
- right = b;
-
-
- var typeLeft:String = typeof(left);
- var typeRight:String = typeof(right);
-
-
- if (typeLeft == "string" || typeRight == "string")
- {
- found = true;
- _compareFunction = stringCompare;
- }
- else if (typeLeft == "object" || typeRight == "object")
- {
- if (left is Date || right is Date)
- {
- found = true;
- _compareFunction = dateCompare;
- }
- }
- else if (typeLeft == "xml" || typeRight == "xml")
- {
- found = true;
- _compareFunction = xmlCompare;
- }
- else if (typeLeft == "number" || typeRight == "number"
- || typeLeft == "boolean" || typeRight == "boolean")
- {
- found = true;
- _compareFunction = numericCompare;
- }
-
- if (found)
- {
- return _compareFunction(left, right);
- }
- else
- {
- var message:String = "";
- resourceManager.getString(
- "collections", "noComparatorSortField", [ name ]);
- throw new SortError(message);
- }
- } */
-
- /**
- * Pull the numbers from the objects and call the implementation.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- /* private function numericCompare(a:Object, b:Object):int
- {
- var fa:Number = _name == null ? Number(a) : Number(getSortFieldValue(a));
- var fb:Number = _name == null ? Number(b) : Number(getSortFieldValue(b));
-
- return ObjectUtil.numericCompare(fa, fb);
- } */
-
- /**
- * Pull the date objects from the values and compare them.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- /* private function dateCompare(a:Object, b:Object):int
- {
- var fa:Date = _name == null ? a as Date : getSortFieldValue(a) as Date;
- var fb:Date = _name == null ? b as Date : getSortFieldValue(b) as Date;
-
- return ObjectUtil.dateCompare(fa, fb);
- } */
-
- /**
- * Pull the strings from the objects and call the implementation.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- /* protected function stringCompare(a:Object, b:Object):int
- {
- var fa:String = _name == null ? String(a) : String(getSortFieldValue(a));
- var fb:String = _name == null ? String(b) : String(getSortFieldValue(b));
-
- return ObjectUtil.stringCompare(fa, fb, _caseInsensitive);
- } */
-
- /**
- * Pull the values out fo the XML object, then compare
- * using the string or numeric comparator depending
- * on the numeric flag.
- *
- * @langversion 3.0
- * @playerversion Flash 9
- * @playerversion AIR 1.1
- * @productversion Royale 0.9.4
- */
- /* protected function xmlCompare(a:Object, b:Object):int
- {
- var sa:String = _name == null ? a.toString() : getSortFieldValue(a).toString();
- var sb:String = _name == null ? b.toString() : getSortFieldValue(b).toString();
-
- if (numeric == true)
- {
- return ObjectUtil.numericCompare(parseFloat(sa), parseFloat(sb));
- }
- else
- {
- return ObjectUtil.stringCompare(sa, sb, _caseInsensitive);
- }
- } */
-}
-}
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.collections
+{
+
+ import org.apache.royale.events.Event;
+ import org.apache.royale.events.EventDispatcher;
+
+ import mx.collections.errors.SortError;
+ import mx.core.mx_internal;
+ //import mx.resources.IResourceManager;
+ //import mx.resources.ResourceManager;
+ import mx.utils.ObjectUtil;
+
+// [ResourceBundle("collections")]
+//[Alternative(replacement="spark.collections.SortField", since="4.5")]
+
+/**
+ * Provides the sorting information required to establish a sort on a field
+ * or property in a collection view.
+ *
+ * The SortField class is meant to be used with the Sort class.
+ *
+ * Typically the sort is defined for collections of complex items, that is
+ * items in which the sort is performed on properties of those objects.
+ * As in the following example:
+ *
+ * <pre><code>
+ * var col:ICollectionView = new ArrayCollection();
+ * col.addItem({first:"Anders", last:"Dickerson"});
+ * var sort:Sort = new Sort();
+ * sort.fields = [new SortField("first", true)];
+ * col.sort = sort;
+ * </code></pre>
+ *
+ * There are situations in which the collection contains simple items, like
+ * <code>String</code>, <code>Date</code>, <code>Boolean</code>, etc.
+ * In this case, sorting should be applied to the simple type directly.
+ * When constructing a sort for this situation only a single sort field is
+ * required and should not have a <code>name</code> specified.
+ * For example:
+ *
+ * <pre><code>
+ * var col:ICollectionView = new ArrayCollection();
+ * col.addItem("California");
+ * col.addItem("Arizona");
+ * var sort:Sort = new Sort();
+ * sort.fields = [new SortField(null, true)];
+ * col.sort = sort;
+ * </code></pre>
+ *
+ * <p>By default the comparison provided by the SortField class does
+ * not provide correct language specific
+ * sorting for strings. For this type of sorting please see the
+ * <code>spark.collections.Sort</code> and
+ * <code>spark.collections.SortField</code> classes.</p>
+ *
+ * Note: to prevent problems like
+ * <a href="https://issues.apache.org/jira/browse/FLEX-34853">FLEX-34853</a>
+ * it is recommended to use SortField
+ * instances as immutable objects (by not changing their state).
+ *
+ * @mxml
+ *
+ * <p>The <code><mx:SortField></code> tag has the following attributes:</p>
+ *
+ * <pre>
+ * <mx:SortField
+ * <b>Properties</b>
+ * caseInsensitive="false"
+ * compareFunction="<em>Internal compare function</em>"
+ * descending="false"
+ * name="null"
+ * numeric="null"
+ * />
+ * </pre>
+ *
+ * @see mx.collections.ICollectionView
+ * @see mx.collections.Sort
+ * @see spark.collections.Sort
+ * @see spark.collections.SortField
+
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class SortField extends EventDispatcher implements ISortField
+{
+// include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @param name The name of the property that this field uses for
+ * comparison.
+ * If the object is a simple type, pass <code>null</code>.
+ * @param caseInsensitive When sorting strings, tells the comparator
+ * whether to ignore the case of the values.
+ * @param descending Tells the comparator whether to arrange items in
+ * descending order.
+ * @param numeric Tells the comparator whether to compare sort items as
+ * numbers, instead of alphabetically.
+ * @param sortCompareType Gives an indication to SortField which of the
+ * default compare functions to use.
+ * @param customCompareFunction Use a custom function to compare the
+ * objects based on this SortField.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function SortField(name:String = null,
+ caseInsensitive:Boolean = false,
+ descending:Boolean = false,
+ numeric:Object = null,
+ sortCompareType:String = null,
+ customCompareFunction:Function = null)
+ {
+ super();
+
+ _name = name;
+ _caseInsensitive = caseInsensitive;
+ _descending = descending;
+ _numeric = numeric;
+ _sortCompareType = sortCompareType;
+
+ if(customCompareFunction != null)
+ {
+ compareFunction = customCompareFunction;
+ }
+ else if (updateSortCompareType() == false)
+ {
+ _compareFunction = stringCompare;
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Used for accessing localized Error messages.
+ */
+ //private var resourceManager:IResourceManager =
+ // ResourceManager.getInstance();
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //---------------------------------
+ // arraySortOnOptions
+ //---------------------------------
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get arraySortOnOptions():int
+ {
+ if (usingCustomCompareFunction
+ || name == null
+ || _compareFunction == xmlCompare
+ || _compareFunction == dateCompare)
+ {
+ return -1;
+ }
+ var options:int = 0;
+ if (caseInsensitive) options |= Array.CASEINSENSITIVE;
+ if (descending) options |= Array.DESCENDING;
+ if (numeric == true || _compareFunction == numericCompare) options |= Array.NUMERIC;
+ return options;
+ }
+
+ //---------------------------------
+ // caseInsensitive
+ //---------------------------------
+
+ /**
+ * @private
+ * Storage for the caseInsensitive property.
+ */
+ private var _caseInsensitive:Boolean;
+
+ [Inspectable(category="General")]
+ [Bindable("caseInsensitiveChanged")]
+
+ /**
+ * Specifies whether the sort for this field should be case insensitive.
+ *
+ * @default false
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get caseInsensitive():Boolean
+ {
+ return _caseInsensitive;
+ }
+
+ /**
+ * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
+ * argument instead.
+ */
+ mx_internal function setCaseInsensitive(value:Boolean):void
+ {
+ if (value != _caseInsensitive)
+ {
+ _caseInsensitive = value;
+ dispatchEvent(new Event("caseInsensitiveChanged"));
+ }
+ }
+
+ //---------------------------------
+ // compareFunction
+ //---------------------------------
+
+ /**
+ * @private
+ * Storage for the compareFunction property.
+ */
+ private var _compareFunction:Function;
+
+ [Inspectable(category="General")]
+
+ /**
+ * The function that compares two items during a sort of items for the
+ * associated collection. If you specify a <code>compareFunction</code>
+ * property in an <code>ISort</code> object, Flex ignores any
+ * <code>compareFunction</code> properties of the ISort's
+ * <code>SortField</code> objects.
+ *
+ * <p>The compare function must have the following signature:</p>
+ *
+ * <p><code>function myCompare(a:Object, b:Object):int</code></p>
+ *
+ * <p>This function must return the following values:</p>
+ *
+ * <ul>
+ * <li>-1, if the <code>Object a</code> should appear before the
+ * <code>Object b</code> in the sorted sequence</li>
+ * <li>0, if the <code>Object a</code> equals the
+ * <code>Object b</code></li>
+ * <li>1, if the <code>Object a</code> should appear after the
+ * <code>Object b</code> in the sorted sequence</li>
+ * </ul>
+ *
+ * <p>The default value is an internal compare function that can perform
+ * a string, numeric, or date comparison in ascending or descending order,
+ * with case-sensitive or case-insensitive string comparisons.
+ * Specify your own function only if you need a need a custom comparison
+ * algorithm. This is normally only the case if a calculated field is
+ * used in a display.</p>
+ *
+ * Note if you need language-specific sorting then consider using the
+ * <code>spark.collections.SortField</code> class.
+ *
+ * @see spark.collections.SortField
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get compareFunction():Function
+ {
+ return _compareFunction;
+ }
+
+ /**
+ * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
+ * argument instead.
+ */
+ public function set compareFunction(c:Function):void
+ {
+ _compareFunction = c;
+ _usingCustomCompareFunction = (c != null);
+ }
+
+ //---------------------------------
+ // descending
+ //---------------------------------
+
+ /**
+ * @private
+ * Storage for the descending property.
+ */
+ private var _descending:Boolean;
+
+ [Inspectable(category="General")]
+ [Bindable("descendingChanged")]
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get descending():Boolean
+ {
+ return _descending;
+ }
+
+ /**
+ * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
+ * argument instead.
+ */
+ public function set descending(value:Boolean):void
+ {
+ if (_descending != value)
+ {
+ _descending = value;
+ dispatchEvent(new Event("descendingChanged"));
+ }
+ }
+
+ //---------------------------------
+ // name
+ //---------------------------------
+
+ /**
+ * @private
+ * Storage for the name property.
+ */
+ private var _name:String;
+
+ [Inspectable(category="General")]
+ [Bindable("nameChanged")]
+
+ /**
+ * @inheritDoc
+ *
+ * @default null
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get name():String
+ {
+ return _name;
+ }
+
+ /**
+ * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
+ * argument instead.
+ */
+ public function set name(n:String):void
+ {
+ _name = n;
+ dispatchEvent(new Event("nameChanged"));
+ }
+
+ //---------------------------------
+ // numeric
+ //---------------------------------
+
+ /**
+ * @private
+ * Storage for the numeric property.
+ */
+ private var _numeric:Object;
+
+ [Inspectable(category="General")]
+ [Bindable("numericChanged")]
+
+ /**
+ * @inheritDoc
+ *
+ * @default null
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get numeric():Object
+ {
+ return _numeric;
+ }
+
+ /**
+ * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
+ * argument instead.
+ */
+ public function set numeric(value:Object):void
+ {
+ if (_numeric != value)
+ {
+ _numeric = value;
+ dispatchEvent(new Event("numericChanged"));
+ }
+ }
+
+
+ //---------------------------------
+ // sortCompareType
+ //---------------------------------
+
+ /**
+ * @private
+ */
+ private var _sortCompareType:String = null;
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11.8
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.11
+ */
+ [Bindable("sortCompareTypeChanged")]
+ public function get sortCompareType():String
+ {
+ return _sortCompareType;
+ }
+
+ /**
+ * @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
+ * argument instead.
+ */
+ public function set sortCompareType(value:String):void
+ {
+ if (_sortCompareType != value)
+ {
+ _sortCompareType = value;
+ dispatchEvent(new Event("sortCompareTypeChanged"));
+ }
+
+ updateSortCompareType();
+ }
+
+
+ //---------------------------------
+ // usingCustomCompareFunction
+ //---------------------------------
+
+ private var _usingCustomCompareFunction:Boolean;
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get usingCustomCompareFunction():Boolean
+ {
+ return _usingCustomCompareFunction;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * A pretty printer for SortField that lists the sort fields and their
+ * options.
+ override public function toString():String
+ {
+ return ObjectUtil.toString(this);
+ }
+ */
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function initializeDefaultCompareFunction(obj:Object):void
+ {
+ // if the compare function is not already set then we can set it
+ if (!usingCustomCompareFunction)
+ {
+ if (_sortCompareType)
+ {
+ //Attempt to set the compare function based on the sortCompareType
+ if (updateSortCompareType() == true)
+ {
+ return;
+ }
+ }
+
+ if (numeric == true)
+ _compareFunction = numericCompare;
+ else if (caseInsensitive || numeric == false)
+ _compareFunction = stringCompare;
+ else
+ {
+ // we need to introspect the data a little bit
+ var value:Object;
+ if (_name)
+ {
+ value = getSortFieldValue(obj);
+ }
+ //this needs to be an == null check because !value will return true
+ //where value == 0 or value == false
+ if (value == null)
+ {
+ value = obj;
+ }
+
+ var typ:String = typeof(value);
+ switch (typ)
+ {
+ case "string":
+ _compareFunction = stringCompare;
+ break;
+ case "object":
+ if (value is Date)
+ {
+ _compareFunction = dateCompare;
+ }
+ else
+ {
+ _compareFunction = stringCompare;
+ var test:String;
+ try
+ {
+ test = value.toString();
+ }
+ catch(error2:Error)
+ {
+ }
+ if (!test || test == "[object Object]")
+ {
+ _compareFunction = nullCompare;
+ }
+ }
+ break;
+ case "xml":
+ _compareFunction = xmlCompare;
+ break;
+ case "boolean":
+ case "number":
+ _compareFunction = numericCompare;
+ break;
+ }
+ } // else
+ } // if
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function reverse():void
+ {
+ descending = !descending;
+ }
+
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11.8
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.11
+ */
+ public function updateSortCompareType():Boolean
+ {
+ if (!_sortCompareType)
+ {
+ return false;
+ }
+
+
+ //Lookup the sortCompareType by its SortFieldCompareTypes value and set the associated compare method.
+ switch(_sortCompareType)
+ {
+ case SortFieldCompareTypes.DATE:
+ {
+ _compareFunction = dateCompare;
+
+ return true;
+ }
+
+ case SortFieldCompareTypes.NULL:
+ {
+ _compareFunction = nullCompare;
+
+ return true;
+ }
+
+ case SortFieldCompareTypes.NUMERIC:
+ {
+ _compareFunction = numericCompare;
+
+ return true;
+ }
+
+ case SortFieldCompareTypes.STRING:
+ {
+ _compareFunction = stringCompare;
+
+ return true;
+ }
+
+ case SortFieldCompareTypes.XML:
+ {
+ _compareFunction = xmlCompare;
+
+ return true;
+ }
+ }
+
+
+ return false;
+ }
+
+
+ public function objectHasSortField(object:Object):Boolean
+ {
+ return getSortFieldValue(object) !== undefined;
+ }
+
+
+ //--------------------------------------------------------------------------
+ //
+ // Protected Methods
+ //
+ //--------------------------------------------------------------------------
+
+ protected function getSortFieldValue(obj:Object):*
+ {
+ var result:* = undefined;
+
+ try
+ {
+ result = obj[_name];
+ }
+ catch(error:Error)
+ {
+ }
+
+ return result;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Private Methods
+ //
+ //--------------------------------------------------------------------------
+
+ private function nullCompare(a:Object, b:Object):int
+ {
+ var left:Object;
+ var right:Object;
+
+ var found:Boolean = false;
+
+ // return 0 (ie equal) if both are null
+ if (a == null && b == null)
+ {
+ return 0;
+ }
+
+ // we need to introspect the data a little bit
+ if (_name)
+ {
+ left = getSortFieldValue(a);
+ right = getSortFieldValue(b);
+ }
+
+ // return 0 (ie equal) if both are null
+ if (left == null && right == null)
+ return 0;
+
+ if (left == null && !_name)
+ left = a;
+
+ if (right == null && !_name)
+ right = b;
+
+
+ var typeLeft:String = typeof(left);
+ var typeRight:String = typeof(right);
+
+
+ if (typeLeft == "string" || typeRight == "string")
+ {
+ found = true;
+ _compareFunction = stringCompare;
+ }
+ else if (typeLeft == "object" || typeRight == "object")
+ {
+ if (left is Date || right is Date)
+ {
+ found = true;
+ _compareFunction = dateCompare;
+ }
+ }
+ else if (typeLeft == "xml" || typeRight == "xml")
+ {
+ found = true;
+ _compareFunction = xmlCompare;
+ }
+ else if (typeLeft == "number" || typeRight == "number"
+ || typeLeft == "boolean" || typeRight == "boolean")
+ {
+ found = true;
+ _compareFunction = numericCompare;
+ }
+
+ if (found)
+ {
+ return _compareFunction(left, right);
+ }
+ else
+ {
+ var message:String = /*resourceManager.getString(
+ "collections", */"noComparatorSortField"/*, [ name ])*/;
+ throw new SortError(message);
+ }
+ }
+
+ /**
+ * Pull the numbers from the objects and call the implementation.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function numericCompare(a:Object, b:Object):int
+ {
+ var fa:Number = _name == null ? Number(a) : Number(getSortFieldValue(a));
+ var fb:Number = _name == null ? Number(b) : Number(getSortFieldValue(b));
+
+ return ObjectUtil.numericCompare(fa, fb);
+ }
+
+ /**
+ * Pull the date objects from the values and compare them.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function dateCompare(a:Object, b:Object):int
+ {
+ var fa:Date = _name == null ? a as Date : getSortFieldValue(a) as Date;
+ var fb:Date = _name == null ? b as Date : getSortFieldValue(b) as Date;
+
+ return ObjectUtil.dateCompare(fa, fb);
+ }
+
+ /**
+ * Pull the strings from the objects and call the implementation.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function stringCompare(a:Object, b:Object):int
+ {
+ var fa:String = _name == null ? String(a) : String(getSortFieldValue(a));
+ var fb:String = _name == null ? String(b) : String(getSortFieldValue(b));
+
+ return ObjectUtil.stringCompare(fa, fb, _caseInsensitive);
+ }
+
+ /**
+ * Pull the values out fo the XML object, then compare
+ * using the string or numeric comparator depending
+ * on the numeric flag.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function xmlCompare(a:Object, b:Object):int
+ {
+ var sa:String = _name == null ? a.toString() : getSortFieldValue(a).toString();
+ var sb:String = _name == null ? b.toString() : getSortFieldValue(b).toString();
+
+ if (numeric == true)
+ {
+ return ObjectUtil.numericCompare(parseFloat(sa), parseFloat(sb));
+ }
+ else
+ {
+ return ObjectUtil.stringCompare(sa, sb, _caseInsensitive);
+ }
+ }
+}
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/SortFieldCompareTypes.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/SortFieldCompareTypes.as
new file mode 100644
index 0000000..119a415
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/SortFieldCompareTypes.as
@@ -0,0 +1,117 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.collections
+{
+
+ /**
+ * The SortFieldCompareTypes class defines the valid constant values for the
+ * <code>sortCompareType</code> property of the <code>SortField</code> and <code>GridColumn</code>.
+ *
+ * <p>Designed to be used from a DataGrids column, but can be referenced directly on the <code>SortField</code></p>
+ *
+ * <p>Use the constants in ActionsScript, as the following example shows:</p>
+ * <pre>
+ * column.sortCompareType = SortFieldCompareTypes.NUMERIC;
+ * </pre>
+ *
+ * <p>In MXML, use the String value of the constants, as the following example shows:</p>
+ * <pre>
+ * <s:GridColumn sortCompareType="numeric" />
+ * </pre>
+ *
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11.8
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.11
+ */
+ public final class SortFieldCompareTypes
+ {
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11.1
+ * @playerversion AIR 3.4
+ * @productversion Flex 4.10
+ */
+ public function SortFieldCompareTypes()
+ {
+ }
+
+ //----------------------------------------
+ // Class constants
+ //----------------------------------------
+
+ /**
+ * Represents the dateCompare inside a SortField.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11.8
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.11
+ */
+ public static const DATE:String = "date";
+
+
+ /**
+ * Represents the nullCompare inside a SortField.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11.8
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.11
+ */
+ public static const NULL:String = "null";
+
+
+ /**
+ * Represents the numericCompare inside a SortField. This also is used for boolean comparisons.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11.8
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.11
+ */
+ public static const NUMERIC:String = "numeric";
+
+
+ /**
+ * Represents the stringCompare inside a SortField.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11.8
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.11
+ */
+ public static const STRING:String = "string";
+
+
+ /**
+ * Represents the xmlCompare inside a SortField.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11.8
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.11
+ */
+ public static const XML:String = "xml";
+ }
+}
\ No newline at end of file
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/XMLListAdapter.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/XMLListAdapter.as
new file mode 100644
index 0000000..350667c
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/XMLListAdapter.as
@@ -0,0 +1,826 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.collections
+{
+
+import org.apache.royale.events.EventDispatcher;
+import org.apache.royale.reflection.getQualifiedClassName;
+import mx.events.CollectionEvent;
+import mx.events.CollectionEventKind;
+import mx.events.PropertyChangeEvent;
+import mx.events.PropertyChangeEventKind;
+//import mx.resources.IResourceManager;
+//import mx.resources.ResourceManager;
+import mx.utils.IXMLNotifiable;
+import mx.utils.XMLNotifier;
+import org.apache.royale.utils.UIDUtil;
+
+//--------------------------------------
+// Events
+//--------------------------------------
+
+/**
+ * Dispatched when the IList has been updated in some way.
+ *
+ * @eventType mx.events.CollectionEvent.COLLECTION_CHANGE
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+[Event(name="collectionChange", type="mx.events.CollectionEvent")]
+
+//--------------------------------------
+// Other metadata
+//--------------------------------------
+
+[ExcludeClass]
+
+//[ResourceBundle("collections")]
+
+/**
+ * @private
+ * A simple implementation of IList that uses a backing XMLList.
+ * No ItemPendingErrors since the data is always local.
+ */
+public class XMLListAdapter extends EventDispatcher implements IList, IXMLNotifiable
+{
+// include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Construct a new XMLListAdapter using the specified XMLList as its source.
+ * If no source is specified an empty XMLList will be used.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function XMLListAdapter(source:XMLList = null)
+ {
+ super();
+
+ disableEvents();
+ this.source = source;
+ enableEvents();
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Used for accessing localized Error messages.
+ */
+ //private var resourceManager:IResourceManager =
+ // ResourceManager.getInstance();
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // length
+ //----------------------------------
+
+ /**
+ * The number of items in this list.
+ *
+ * @return -1 if the length is unknown while 0 means no items
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get length():int
+ {
+ return source.length();
+ }
+
+ //----------------------------------
+ // source
+ //----------------------------------
+
+ private var _source:XMLList;
+
+ /**
+ * The source XMLList for this XMLListAdapter.
+ * Any changes done through the IList interface will be reflected in the
+ * source XMLList.
+ * If no source XMLList was supplied the XMLListAdapter will create one
+ * internally.
+ * Changes made directly to the underlying XMLList (e.g., calling
+ * <code>delete theList[someIndex]</code> will not cause <code>CollectionEvents</code>
+ * to be dispatched.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get source():XMLList
+ {
+ return _source;
+ }
+
+ public function set source(s:XMLList):void
+ {
+ var i:int;
+ var len:int;
+ if (_source && _source.length())
+ {
+ len = _source.length();
+ for (i = 0; i < len; i++)
+ {
+ stopTrackUpdates(_source[i]);
+ }
+ }
+ _source = s ? s : XMLList(<></>);
+
+ // get a seed UID. XML seems to have problems cleaning up
+ // UIDs, so this makes UIDs more similar and uses less
+ // memory
+ seedUID = UIDUtil.createUID();
+ uidCounter = 0;
+
+ len = _source.length();
+ for (i = 0; i < len; i++)
+ {
+ startTrackUpdates(_source[i], seedUID + uidCounter.toString());
+ uidCounter++;
+ }
+
+ if (_dispatchEvents == 0)
+ {
+ var event:CollectionEvent =
+ new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = CollectionEventKind.RESET;
+ dispatchEvent(event);
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Add the specified item to the end of the list.
+ * Equivalent to addItemAt(item, length);
+ * @param item the item to add
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function addItem(item:Object):void
+ {
+ addItemAt(item, length);
+ }
+
+ /**
+ * Add the item at the specified index. Any item that was after
+ * this index is moved out by one. If the list is shorter than
+ * the specified index it will grow to accomodate the new item.
+ *
+ * @param item the item to place at the index
+ * @param index the index at which to place the item
+ * @throws RangeError if index is less than 0
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function addItemAt(item:Object, index:int):void
+ {
+ var message:String;
+
+ /*
+ if (index < 0 || index > length)
+ {
+ message = resourceManager.getString(
+ "collections", "outOfBounds", [ index ]);
+ throw new RangeError(message);
+ }
+
+ if (!(item is XML) && !(item is XMLList && item.length() == 1))
+ {
+ message = resourceManager.getString(
+ "collections", "invalidType");
+ throw new Error(message);
+ }
+ */
+
+ setBusy();
+
+ if (length > 0)
+ {
+ var localLength:uint = source.length();
+
+ // Adjust all indexes by 1
+ for (var i:uint = localLength; i>index; i--)
+ {
+ source[i] = source[i - 1];
+ }
+ }
+
+ source[index] = item;
+
+ startTrackUpdates(item, seedUID + uidCounter.toString());
+ uidCounter++;
+
+ if (_dispatchEvents == 0)
+ {
+ var event:CollectionEvent =
+ new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = CollectionEventKind.ADD;
+ event.items.push(item);
+ event.location = index;
+ dispatchEvent(event);
+ }
+
+ clearBusy();
+ }
+
+ /**
+ * Get the item at the specified index.
+ *
+ * @param index the index in the list from which to retrieve the item
+ * @param prefetch int indicating both the direction and amount of items
+ * to fetch during the request should the item not be local.
+ * @return the item at that index, null if there is none
+ * @throws ItemPendingError if the data for that index needs to be
+ * loaded from a remote location
+ * @throws RangeError if the index < 0 or index >= length
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function getItemAt(index:int, prefetch:int = 0):Object
+ {
+ /*
+ if (index < 0 || index >= length)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "outOfBounds", [ index ]);
+ throw new RangeError(message);
+ }
+ */
+
+ return source[index];
+ }
+
+ /**
+ * Return the index of the item if it is in the list such that
+ * getItemAt(index) == item. Note: unlike IViewCursor.findXXX
+ * <code>getItemIndex</code> cannot take a representative object, it is
+ * searching for an exact match.
+ *
+ * @param item the item to find
+ * @return the index of the item, -1 if the item is not in the list.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function getItemIndex(item:Object):int
+ {
+ if (item is XML && source.contains(XML(item)))
+ {
+ var len:int = length;
+ for (var i:int = 0; i < len; i++)
+ {
+ var search:Object = source[i];
+ if (search === item)
+ {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Notify the view that an item has been updated. This is useful if the
+ * contents of the view do not implement <code>IEventDispatcher</code>
+ * and dispatches a <code>PropertyChangeEvent</code>. If a property
+ * is specified the view may be able to optimize its notification mechanism.
+ * Otherwise it may choose to simply refresh the whole view.
+ *
+ * @param item The item within the view that was updated.
+ *
+ * @param property A String, QName, or int
+ * specifying the property that was updated.
+ *
+ * @param oldValue The old value of that property.
+ * (If property was null, this can be the old value of the item.)
+ *
+ * @param newValue The new value of that property.
+ * (If property was null, there's no need to specify this
+ * as the item is assumed to be the new value.)
+ *
+ * @see mx.events.CollectionEvent
+ * @see mx.core.IPropertyChangeNotifier
+ * @see mx.events.PropertyChangeEvent
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function itemUpdated(item:Object, property:Object = null,
+ oldValue:Object = null,
+ newValue:Object = null):void
+ {
+ var event:PropertyChangeEvent =
+ new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
+
+ event.kind = PropertyChangeEventKind.UPDATE;
+ event.source = item;
+ event.property = property;
+ event.oldValue = oldValue;
+ event.newValue = newValue;
+
+ itemUpdateHandler(event);
+ }
+
+ /**
+ * Remove all items from the list.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function removeAll():void
+ {
+ if (length > 0)
+ {
+ for (var i:int=length - 1; i >= 0; i--)
+ {
+ stopTrackUpdates(source[i]);
+ delete source[i];
+ }
+
+ if (_dispatchEvents == 0)
+ {
+ var event:CollectionEvent =
+ new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = CollectionEventKind.RESET;
+ dispatchEvent(event);
+ }
+ }
+ }
+
+ /**
+ * Removes the specified item from this list, should it exist.
+ * Relies on ArrayList implementation
+ *
+ * @param item Object reference to the item that should be removed.
+ * @return Boolean indicating if the item was removed.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Apache Flex 4.10
+ */
+ public function removeItem( item:Object ):Boolean
+ {
+ var _item:Object = removeItemAt(getItemIndex(item));
+ return _item != null;
+ }
+
+ /**
+ * Remove the item at the specified index and return it. Any items
+ * that were after this index are now one index earlier.
+ *
+ * @param index the index from which to remove the item
+ * @return the item that was removed
+ * @throws RangeError is index is less than 0 or greater than length
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function removeItemAt(index:int):Object
+ {
+ /*
+ if (index < 0 || index >= length)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "outOfBounds", [ index ]);
+ throw new RangeError(message);
+ }
+ */
+
+ setBusy();
+
+ var removed:Object = source[index];
+ delete source[index];
+ stopTrackUpdates(removed);
+ if (_dispatchEvents == 0)
+ {
+ var event:CollectionEvent =
+ new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = CollectionEventKind.REMOVE;
+ event.location = index;
+ event.items.push(removed);
+ dispatchEvent(event);
+ }
+
+ clearBusy();
+
+ return removed;
+ }
+
+ /**
+ * Place the item at the specified index. If an item was already
+ * at that index the new item will replace it and it will be returned.
+ * If the list is shorter than the specified index it will grow to
+ * to accomodate the new item.
+ *
+ * @param item the new value for the index
+ * @param index the index at which to place the item
+ * @return the item that was replaced, null if none
+ * @throws RangeError if index is less than 0
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function setItemAt(item:Object, index:int):Object
+ {
+ /*
+ if (index < 0 || index >= length)
+ {
+ var message:String = resourceManager.getString(
+ "collections", "outOfBounds", [ index ]);
+ throw new RangeError(message);
+ }
+ */
+
+ var oldItem:Object = source[index];
+ source[index] = item;
+ stopTrackUpdates(oldItem);
+ startTrackUpdates(item, seedUID + uidCounter.toString());
+ uidCounter++;
+
+ if (_dispatchEvents == 0)
+ {
+ var event:CollectionEvent =
+ new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = CollectionEventKind.REPLACE;
+ var updateInfo:PropertyChangeEvent =
+ new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
+ updateInfo.kind = PropertyChangeEventKind.UPDATE;
+ updateInfo.oldValue = oldItem;
+ updateInfo.newValue = item;
+ event.location = index;
+ event.items.push(updateInfo);
+ dispatchEvent(event);
+ }
+ return oldItem;
+ }
+
+ /**
+ * Return an Array that is populated in the same order as the IList
+ * implementation.
+ *
+ * @throws ItemPendingError if the data is not yet completely loaded
+ * from a remote location
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function toArray():Array
+ {
+ var s:XMLList = source;
+ var len:int = s.length();
+ var ret:Array = [];
+ for (var i:int = 0; i < len; i++)
+ {
+ ret[i] = s[i];
+ }
+ return ret;
+ }
+
+ /**
+ * Pretty prints the contents of this XMLListAdapter to a string and returns it.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ override public function toString():String
+ {
+ if (source)
+ return source.toString();
+ else
+ return getQualifiedClassName(this);
+ }
+
+ /**
+ * True if we're processing a addItem or removeItem call
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function busy():Boolean
+ {
+ return (_busy != 0)
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Internal Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Enables event dispatch for this list.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function enableEvents():void
+ {
+ _dispatchEvents++;
+ if (_dispatchEvents > 0)
+ _dispatchEvents = 0;
+ }
+
+ /**
+ * Disables event dispatch for this list.
+ * To re-enable events call enableEvents(), enableEvents() must be called
+ * a matching number of times as disableEvents().
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function disableEvents():void
+ {
+ _dispatchEvents--;
+ }
+
+ /**
+ * clears busy flag
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function clearBusy():void
+ {
+ _busy++;
+ if (_busy > 0)
+ _busy = 0;
+ }
+
+ /**
+ * Sets busy flag. Tree DP's check it so they
+ * know whether to fake events for it or not.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function setBusy():void
+ {
+ _busy--;
+ }
+
+ /**
+ * Called whenever any of the contained items in the list fires a
+ * <code>PropertyChangeEvent</code>.
+ * Wraps it in a CollectionEventKind.UPDATE.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function itemUpdateHandler(event:PropertyChangeEvent):void
+ {
+ if (_dispatchEvents == 0)
+ {
+ var updateEvent:CollectionEvent =
+ new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ updateEvent.kind = CollectionEventKind.UPDATE;
+ updateEvent.items.push(event);
+ dispatchEvent(updateEvent);
+ }
+ }
+
+ /**
+ * Called whenever an XML object contained in our list is updated
+ * in some way. The initial implementation stab is very lenient,
+ * any changeType will cause an update no matter how much further down
+ * in a hierarchy.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function xmlNotification(currentTarget:Object,
+ type:String,
+ target:Object,
+ value:Object,
+ detail:Object):void
+ {
+ var prop:String;
+ var oldValue:Object;
+ var newValue:Object;
+
+ if (currentTarget === target)
+ {
+ switch(type)
+ {
+ case "attributeAdded":
+ {
+ prop = "@" + String(value);
+ newValue = detail;
+ break;
+ }
+
+ case "attributeChanged":
+ {
+ prop = "@" + String(value);
+ oldValue = detail;
+ newValue = target[prop];
+ break;
+ }
+
+ case "attributeRemoved":
+ {
+ prop = "@" + String(value);
+ oldValue = detail;
+ break;
+ }
+
+ case "nodeAdded":
+ {
+ prop = value.localName();
+ newValue = value;
+ break;
+ }
+
+ case "nodeChanged":
+ {
+ prop = value.localName();
+ oldValue = detail;
+ newValue = value;
+ break;
+ }
+
+ case "nodeRemoved":
+ {
+ prop = value.localName();
+ oldValue = value;
+ break;
+ }
+
+ case "textSet":
+ {
+ prop = String(value);
+ newValue = String(target[prop]);
+ oldValue = detail;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+ else if (type == "textSet")
+ {
+ var par:* = target.parent();
+ if (par != undefined)
+ {
+ var gpar:* = par.parent();
+ if (gpar === currentTarget)
+ {
+ prop = par.name().toString();
+ newValue = value;
+ oldValue = detail;
+ }
+ }
+ }
+
+ itemUpdated(currentTarget, prop, oldValue, newValue);
+ }
+
+ /**
+ * This is called by addItemAt and when the source is initially
+ * assigned.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function startTrackUpdates(item:Object, uid:String):void
+ {
+ XMLNotifier.getInstance().watchXML(item, this, uid);
+ }
+
+ /**
+ * This is called by removeItemAt, removeAll, and before a new
+ * source is assigned.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function stopTrackUpdates(item:Object):void
+ {
+ XMLNotifier.getInstance().unwatchXML(item, this);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * indicates if events should be dispatched.
+ * calls to enableEvents() and disableEvents() effect the value when == 0
+ * events should be dispatched.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private var _dispatchEvents:int = 0;
+
+ /**
+ * non-zero if we're processing an addItem or removeItem
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private var _busy:int = 0;
+
+ private var seedUID:String;
+
+ private var uidCounter:int = 0;
+
+}
+
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/XMLListCollection.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/XMLListCollection.as
index 354e32f..91c2e1e 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/XMLListCollection.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/XMLListCollection.as
@@ -20,8 +20,8 @@
package mx.collections
{
-/* [DefaultProperty("source")]
- */
+[DefaultProperty("source")]
+
/**
* The XMLListCollection class provides collection functionality to
* an XMLList object and makes available some of the methods of
@@ -45,12 +45,12 @@ package mx.collections
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
- * @productversion Royale 0.9.3
+ * @productversion Flex 3
*/
-public class XMLListCollection
+public class XMLListCollection extends ListCollectionView
{
-/* include "../core/Version.as";
- */
+// include "../core/Version.as";
+
//--------------------------------------------------------------------------
//
// Constructor
@@ -69,16 +69,398 @@ public class XMLListCollection
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
- * @productversion Royale 0.9.3
+ * @productversion Flex 3
*/
- public function XMLListCollection(source:Object = null)
+ public function XMLListCollection(source:XMLList = null)
{
super();
- // this.source = source;
+ this.source = source;
}
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // source
+ //----------------------------------
+
+ [Inspectable(category="General")]
+ [Bindable("listChanged")] //superclass will fire this
+ /**
+ * The underlying XMLList for this collection.
+ * The XMLListCollection object does not represent any changes that
+ * you make directly to the source XMLList object.
+ * Always use the XMLListCollection methods to modify the collection.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get source():XMLList
+ {
+ return list ? XMLListAdapter(list).source : null;
+ }
+
+ /**
+ * @private
+ */
+ public function set source(s:XMLList):void
+ {
+ if (list)
+ XMLListAdapter(list).source = null;
+
+ list = new XMLListAdapter(s);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Calls the <code>attribute()</code> method of each XML object in the
+ * XMLList and returns an XMLList of the results, which
+ * match the given <code>attributeName</code>.
+ *
+ * @param attributeName The attribute that you want to match in the XML
+ * objects of the XMLList.
+ *
+ * @return The XMLList of matching XML objects.
+ *
+ * @see XML#attribute()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function attribute(attributeName:Object):XMLList
+ {
+ return execXMLListFunction(
+ function(obj:Object):XMLList
+ {
+ return obj.attribute(attributeName);
+ }
+ );
+ }
+
+ /**
+ * Calls the <code>attributes()</code> method of each XML object in the
+ * XMLList object and returns an XMList of attributes for each XML object.
+ *
+ * @return The XMLList containing the resulting XML objects, listing
+ * the attributes.
+ *
+ * @see XML#attributes()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function attributes():XMLList
+ {
+ return execXMLListFunction(
+ function(obj:Object):XMLList
+ {
+ return obj.attributes();
+ }
+ );
+ }
+
+ /**
+ * Calls the <code>child()</code> method of each XML object in the XMLList
+ * and returns an XMLList containing the children of with the specified property
+ * name, in order.
+ *
+ * @param propertyName The propery to match.
+ *
+ * @return An XMLList of matching children of the XML objects in the
+ * original XMLList.
+ *
+ * @see XML#child()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function child(propertyName:Object):XMLList
+ {
+ return execXMLListFunction(
+ function(obj:Object):XMLList
+ {
+ return obj.child(propertyName);
+ }
+ );
+ }
+
+ /**
+ * Calls the children() method of each XML object in the XMLList and
+ * returns an XMLList containing the results.
+ *
+ * @return An XMLList of children of the XML objects in the original XMLList.
+ *
+ * @see XML#children()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function children():XMLList
+ {
+ return execXMLListFunction(
+ function(obj:Object):XMLList
+ {
+ return obj.children();
+ }
+ );
+ }
+
+ /**
+ * Returns a deep copy of the XMLList object.
+ *
+ * @return The copy of the XMLList object.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function copy():XMLList
+ {
+ return execXMLListFunction(
+ function(obj:Object):XMLList
+ {
+ // sometimes the obj can be of type XML
+ return XMLList(obj.copy());
+ }
+ );
+ }
+
+ /**
+ * Calls the <code>descendants()</code> method of each XML object in the
+ * XMLList and returns an XMLList containing the results.
+ * The <code>name</code> parameter is passed to the XML object's
+ * <code>descendants()</code> method.
+ * If you do not specify a parameter, the string "~~" is passed to the
+ * <code>descendants()</code> method.
+ *
+ * @param name The name of the elements to match.
+ *
+ * @return XMLList of the matching descendents (children, grandchildren,
+ * etc.) of the XML objects in the original XMLList.
+ *
+ * @see XML#descendants()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function descendants(name:Object="*"):XMLList
+ {
+ return execXMLListFunction(
+ function(obj:Object):XMLList
+ {
+ return obj.descendants(name);
+ }
+ );
+ }
+
+ /**
+ * Calls the <code>elements()</code> method of each XML object in the XMLList.
+ * The <code>name</code> parameter is passed to the XML object's
+ * <code>elements()</code> method.
+ * If you do not specify a parameter, the string "~~" is passed to the
+ * <code>elements()</code> method.
+ *
+ * @param name The name of the elements to match.
+ *
+ * @return XMLList of the matching child elements of the XML objects in the
+ * original XMLList.
+ *
+ * @see XML#elements()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function elements(name:String="*"):XMLList
+ {
+ return execXMLListFunction(
+ function(obj:Object):XMLList
+ {
+ return obj.elements(name);
+ }
+ );
+ }
+
+ /**
+ * Calls the <code>text()</code> method of each XML object in
+ * the XMLList and returns an XMLList containing the results.
+ *
+ * @return The XMLList that contains the result.
+ *
+ * @see XML#text()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function text():XMLList
+ {
+ return execXMLListFunction(
+ function(obj:Object):XMLList
+ {
+ return obj.text();
+ }
+ );
+ }
+
+ /**
+ * Returns a string representation of the XMLList by calling the
+ * <code>toString()</code> method for each XML object in the XMLList.
+ * If the <code>prettyPrinting</code> property of the <code>XML</code>
+ * class is set to <code>true</code>, then the results for each XML object
+ * in the XMLList are separated by the return character.
+ * Otherwise, if <code>prettyPrinting</code> is set to <code>false</code>,
+ * then the results are simply concatenated, without separating return characters.
+ *
+ * <p>The <code>toString()</code> method strips out the following
+ * in the returned string for an XML object that has simple content:
+ * the start tag, attributes, namespace declarations, and the end tag.
+ * Use the <code>toXMLString()</code> method if you want to preserve these
+ * in the returned string for XML objects with simple content.</p>
+ *
+ * @return The string representation of the XMLList object.
+ *
+ * @see XML#prettyPrinting
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ override public function toString():String
+ {
+ if (!localIndex)
+ {
+ return source.toString();
+ }
+ else
+ {
+ var str:String = "";
+
+ for (var i:int = 0; i < localIndex.length; i++)
+ {
+ if (i > 0)
+ str += "\n"; // this matches how XML works
+
+ str += localIndex[i].toString();
+ }
+
+ return str;
+ }
+ }
+
+ /**
+ * Returns a string representation of the XMLList by calling the
+ * <code>toXMLString()</code> method for each XML object in the XMLList.
+ * If the <code>prettyPrinting</code> property of the <code>XML</code>
+ * class is set to <code>true</code>, then the results for each XML object
+ * in the XMLList are separated by the return character.
+ * Otherwise, if <code>prettyPrinting</code> is set to <code>false</code>,
+ * then the results are concatenated, without separating return
+ * characters.
+ *
+ * <p>The <code>toXMLString()</code> method preserves the
+ * following in the returned string for an XML object that has simple content:
+ * the start tag, attributes, namespace declarations, and the end tag.
+ * Use the <code>toString()</code> method if you want to strip these from
+ * the returned string for XML objects with simple content.</p>
+ *
+ * @return The string representation of the XMLList.
+ *
+ * @see XML#prettyPrinting
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function toXMLString():String
+ {
+ if (!localIndex)
+ {
+ return source.toXMLString();
+ }
+ else
+ {
+ var str:String = "";
+
+ for (var i:int = 0; i < localIndex.length; i++)
+ {
+ if (i > 0)
+ str += "\n"; // this matches how XML works
+
+ str += localIndex[i].toXMLString();
+ }
+
+ return str;
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Internal methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * XMLList doesn't allow you to do myList[funcName](arg) because
+ * it will attempt to lookup a node named funcName instead (despite
+ * the fact that it should be a callProperty()). So instead
+ * the above methods will build little functions that call the
+ * right thing, but the looping logic has been factored into here.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function execXMLListFunction(func:Function):XMLList
+ {
+ if (!localIndex)
+ {
+ return func(source);
+ }
+ else
+ {
+ //create an XML object that will be a host for all the results
+ //go through each child in the order specified by the index
+ //and append the XMLList that results from a call on it to the
+ //return object.
+ var length:int = localIndex.length;
+ var ret:XMLList = new XMLList(); // was this literal <></>;
+ for (var i:int = 0; i < length; i++)
+ {
+ var xml:Object = localIndex[i];
+ ret += func(xml);
+ }
+ return ret;
+ }
+ }
}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/XMLListCollection.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/errors/CursorError.as
similarity index 57%
copy from frameworks/projects/MXRoyale/src/main/royale/mx/collections/XMLListCollection.as
copy to frameworks/projects/MXRoyale/src/main/royale/mx/collections/errors/CursorError.as
index 354e32f..2c9340b 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/XMLListCollection.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/errors/CursorError.as
@@ -17,69 +17,43 @@
//
////////////////////////////////////////////////////////////////////////////////
-package mx.collections
+package mx.collections.errors
{
-/* [DefaultProperty("source")]
- */
/**
- * The XMLListCollection class provides collection functionality to
- * an XMLList object and makes available some of the methods of
- * the native XMLList class.
- *
- * @mxml
- *
- * <p>The <code><mx:XMLListCollection></code> tag inherits all
- * the attributes of its superclass, and adds the following attributes:</p>
- *
- * <pre>
- * <mx:XMLListCollection
- * <b>Properties</b>
- * source="null"
- * />
- * </pre>
- *
- * @see XMLList
- * @see XML
+ * This error is thrown by a collection Cursor.
+ * Errors of this class are thrown by classes
+ * that implement the IViewCursor interface.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
- * @productversion Royale 0.9.3
+ * @productversion Flex 3
*/
-public class XMLListCollection
+public class CursorError extends Error
{
-/* include "../core/Version.as";
- */
+// include "../../core/Version.as";
+
//--------------------------------------------------------------------------
//
- // Constructor
+ // Constructor.
//
//--------------------------------------------------------------------------
-
+
/**
* Constructor.
*
- * <p>Creates a new XMLListCollection object
- * using the specified XMLList object.</p>
- *
- * @param source The XMLList object containing the data to be represented
- * by the XMLListCollection object.
+ * @param message A message providing information about the error cause.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
- * @productversion Royale 0.9.3
+ * @productversion Flex 3
*/
- public function XMLListCollection(source:Object = null)
+ public function CursorError(message:String)
{
- super();
-
- // this.source = source;
+ super(message);
}
-
-
-
}
}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/Tree.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/Tree.as
index c9f5b4b..09726dd 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/Tree.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/Tree.as
@@ -36,7 +36,7 @@ import flash.ui.Keyboard;
import flash.utils.clearInterval;
import flash.utils.getTimer;
import flash.xml.XMLNode; */
-//import mx.collections.ArrayCollection;
+import mx.collections.ArrayCollection;
import mx.collections.CursorBookmark;
import mx.collections.ICollectionView;
//import mx.collections.ItemResponder;
@@ -48,11 +48,11 @@ import mx.controls.listClasses.BaseListData;
//import mx.controls.listClasses.IListItemRenderer;
//import mx.controls.listClasses.ListRowInfo;
//import mx.controls.listClasses.ListBaseSelectionDataPending;
-//import mx.controls.treeClasses.DefaultDataDescriptor;
-//import mx.controls.treeClasses.HierarchicalCollectionView;
-//import mx.controls.treeClasses.HierarchicalViewCursor;
+import mx.controls.treeClasses.DefaultDataDescriptor;
+import mx.controls.treeClasses.HierarchicalCollectionView;
+import mx.controls.treeClasses.HierarchicalViewCursor;
import mx.controls.treeClasses.ITreeDataDescriptor;
-//import mx.controls.treeClasses.ITreeDataDescriptor2;
+import mx.controls.treeClasses.ITreeDataDescriptor2;
import mx.controls.treeClasses.TreeItemRenderer;
import mx.controls.treeClasses.TreeListData;
import mx.core.ClassFactory;
@@ -690,7 +690,7 @@ public class Tree extends List
* @playerversion AIR 1.1
* @productversion Royale 0.9.3
*/
- //mx_internal var wrappedCollection:ICollectionView;
+ mx_internal var wrappedCollection:ICollectionView;
/**
* @private
@@ -726,12 +726,11 @@ public class Tree extends List
/**
* @private
*/
-/* private var dataProviderChanged:Boolean = false;
+ private var dataProviderChanged:Boolean = false;
[Bindable("collectionChange")]
[Inspectable(category="Data", defaultValue="null")]
- */
/**
* An object that contains the data to be displayed.
* When you assign a value to this property, the Tree class handles
@@ -757,16 +756,20 @@ public class Tree extends List
override public function set dataProvider(value:Object):void
{
// in all cases save off the original
- /* if (_rootModel)
+ /* later
+ if (_rootModel)
_rootModel.removeEventListener(
CollectionEvent.COLLECTION_CHANGE,
collectionChangeHandler);
-
+ */
+
// handle strings and xml
if (typeof(value)=="string")
value = new XML(value);
+ /*
else if (value is XMLNode)
value = new XML(XMLNode(value).toString());
+ */
else if (value is XMLList)
value = new XMLListCollection(value as XMLList);
@@ -803,7 +806,11 @@ public class Tree extends List
}
//flag for processing in commitProps
dataProviderChanged = true;
- invalidateProperties(); */
+ //invalidateProperties();
+
+ // the above is Flex code. Only this line below was added
+ // to get it to work without the validation mechanism.
+ commitProperties();
}
/**
@@ -811,9 +818,8 @@ public class Tree extends List
*/
override public function get dataProvider():Object
{
- /* if (_rootModel)
+ if (_rootModel)
return _rootModel;
- */
return null;
}
@@ -1029,13 +1035,13 @@ public class Tree extends List
* @private
* Flag to indicate if the model has a root
*/
- //mx_internal var _hasRoot:Boolean = false;
+ mx_internal var _hasRoot:Boolean = false;
/**
* @private
* Storage variable for the original dataProvider
*/
- //mx_internal var _rootModel:ICollectionView;
+ mx_internal var _rootModel:ICollectionView;
//[Inspectable(category="Data", enumeration="true,false", defaultValue="false")]
@@ -1163,27 +1169,29 @@ public class Tree extends List
/**
* @private
*/
- /* override protected function commitProperties():void
+ override protected function commitProperties():void
{
+ /*
if (showRootChanged)
{
if (!_hasRoot)
showRootChanged = false;
}
+ */
- if (dataProviderChanged || showRootChanged || openItemsChanged)
+ if (dataProviderChanged/* || showRootChanged || openItemsChanged*/)
{
var tmpCollection:ICollectionView;
//reset flags
dataProviderChanged = false;
- showRootChanged = false;
+ //showRootChanged = false;
//we always reset the open and selected items on a dataprovider assignment
- if (!openItemsChanged)
+ //if (!openItemsChanged)
_openItems = {};
- openItemsChanged = false;
+ //openItemsChanged = false;
// are we swallowing the root?
if (_rootModel && !_showRoot && _hasRoot)
@@ -1214,11 +1222,13 @@ public class Tree extends List
_openItems);
+ /* later
// not really a default handler, but we need to be later than the wrapper
wrappedCollection.addEventListener(CollectionEvent.COLLECTION_CHANGE,
collectionChangeHandler,
false,
EventPriority.DEFAULT_HANDLER, true);
+ */
}
else
{
@@ -1226,8 +1236,8 @@ public class Tree extends List
}
}
- super.commitProperties();
- } */
+ //super.commitProperties();
+ }
/**
* @private
@@ -1597,12 +1607,12 @@ public class Tree extends List
* wraps calls to the descriptor
* mx_internal for automation delegate access
*/
- /* mx_internal function getChildren(item:Object, view:Object):ICollectionView
+ mx_internal function getChildren(item:Object, view:Object):ICollectionView
{
//get the collection of children
var children:ICollectionView = _dataDescriptor.getChildren(item, view);
return children;
- } */
+ }
/**
* Determines the number of parents from root to the specified item.
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/beads/models/SingleSelectionICollectionViewModel.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/beads/models/SingleSelectionICollectionViewModel.as
new file mode 100644
index 0000000..9a79fb8
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/beads/models/SingleSelectionICollectionViewModel.as
@@ -0,0 +1,271 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package mx.controls.beads.models
+{
+ import mx.collections.ICollectionView;
+ import mx.collections.IViewCursor;
+ import mx.collections.CursorBookmark;
+
+ import org.apache.royale.core.IRollOverModel;
+ import org.apache.royale.core.ISelectionModel;
+ import org.apache.royale.core.IStrand;
+ import org.apache.royale.events.Event;
+ import org.apache.royale.events.EventDispatcher;
+
+ /**
+ * The SingleSelectionICollectionViewModel class is a selection model for
+ * a dataProvider that is an ICollectionView.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public class SingleSelectionICollectionViewModel extends EventDispatcher implements ISelectionModel, IRollOverModel
+ {
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function SingleSelectionICollectionViewModel()
+ {
+ }
+
+ private var _strand:IStrand;
+
+ /**
+ * @copy org.apache.royale.core.IBead#strand
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function set strand(value:IStrand):void
+ {
+ _strand = value;
+ }
+
+ private var _dataProvider:ICollectionView;
+ private var _cursor:IViewCursor;
+
+ /**
+ * @copy org.apache.royale.core.ISelectionModel#dataProvider
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function get dataProvider():Object
+ {
+ return _dataProvider;
+ }
+
+ /**
+ * @private
+ * @royaleignorecoercion org.apache.royale.collections.IList
+ */
+ public function set dataProvider(value:Object):void
+ {
+ if (value == _dataProvider) return;
+
+ _dataProvider = value as ICollectionView;
+ _cursor = _dataProvider.createCursor();
+ if(!_dataProvider || _selectedIndex >= _dataProvider.length)
+ _selectedIndex = -1;
+
+ _selectedItem = _selectedIndex == -1 ? null : getItemAt(_selectedIndex);
+
+ dispatchEvent(new Event("dataProviderChanged"));
+ }
+
+ private var lastIndex:int = -1;
+ private function getItemAt(index:int):Object
+ {
+ if (index == 0)
+ {
+ if (lastIndex == 1)
+ _cursor.movePrevious();
+ else
+ _cursor.seek(CursorBookmark.FIRST);
+ lastIndex = 0;
+ }
+ else if (index + 1 == lastIndex)
+ _cursor.movePrevious();
+ else if (lastIndex + 1 == index)
+ _cursor.moveNext();
+ else
+ _cursor.seek(CursorBookmark.FIRST, index);
+ return _cursor.current;
+ }
+
+ private var _selectedIndex:int = -1;
+ private var _rollOverIndex:int = -1;
+ private var _labelField:String = null;
+
+ /**
+ * @copy org.apache.royale.core.ISelectionModel#labelField
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function get labelField():String
+ {
+ return _labelField;
+ }
+
+ /**
+ * @private
+ */
+ public function set labelField(value:String):void
+ {
+ if (value != _labelField) {
+ _labelField = value;
+ dispatchEvent(new Event("labelFieldChanged"));
+ }
+ }
+
+ /**
+ * @copy org.apache.royale.core.ISelectionModel#selectedIndex
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function get selectedIndex():int
+ {
+ return _selectedIndex;
+ }
+
+ /**
+ * @private
+ */
+ public function set selectedIndex(value:int):void
+ {
+ if (value == _selectedIndex) return;
+
+ _selectedIndex = value;
+ _selectedItem = (value == -1 || _dataProvider == null) ? null : (value < _dataProvider.length) ? getItemAt(value) : null;
+ dispatchEvent(new Event("selectedIndexChanged"));
+ }
+
+ /**
+ * @copy org.apache.royale.core.IRollOverModel#rollOverIndex
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function get rollOverIndex():int
+ {
+ return _rollOverIndex;
+ }
+
+ /**
+ * @private
+ */
+ public function set rollOverIndex(value:int):void
+ {
+ if (value != _rollOverIndex) {
+ _rollOverIndex = value;
+ dispatchEvent(new Event("rollOverIndexChanged"));
+ }
+ }
+
+ private var _selectedItem:Object;
+
+ /**
+ * @copy org.apache.royale.core.ISelectionModel#selectedItem
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function get selectedItem():Object
+ {
+ return _selectedItem;
+ }
+
+ /**
+ * @private
+ */
+ public function set selectedItem(value:Object):void
+ {
+ if (value == _selectedItem) return;
+
+ _selectedItem = value;
+ var n:int = _dataProvider.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ if (getItemAt(i) == value)
+ {
+ _selectedIndex = i;
+ break;
+ }
+ }
+ dispatchEvent(new Event("selectedItemChanged"));
+ dispatchEvent(new Event("selectedIndexChanged"));
+ }
+
+ private var _selectedString:String;
+
+ /**
+ * An alternative to selectedItem for strongly typing the
+ * the selectedItem if the Array is an Array of Strings.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function get selectedString():String
+ {
+ return String(_selectedItem);
+ }
+
+ /**
+ * @private
+ */
+ public function set selectedString(value:String):void
+ {
+ _selectedString = value;
+ var n:int = _dataProvider.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ if (String(getItemAt(i)) == value)
+ {
+ _selectedIndex = i;
+ break;
+ }
+ }
+ dispatchEvent(new Event("selectedItemChanged"));
+ dispatchEvent(new Event("selectedIndexChanged"));
+ }
+ }
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/beads/models/SingleSelectionIListModel.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/beads/models/SingleSelectionIListModel.as
new file mode 100644
index 0000000..4bb6e7f
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/beads/models/SingleSelectionIListModel.as
@@ -0,0 +1,247 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package mx.controls.beads.models
+{
+ import mx.collections.IList;
+ import org.apache.royale.core.IRollOverModel;
+ import org.apache.royale.core.ISelectionModel;
+ import org.apache.royale.core.IStrand;
+ import org.apache.royale.events.Event;
+ import org.apache.royale.events.EventDispatcher;
+
+ /**
+ * The SingleSelectionIListViewModel class is a selection model for
+ * a dataProvider that is an IList. It assumes that items
+ * can be fetched from the dataProvider using dataProvider.getItemAt(index).
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public class SingleSelectionIListModel extends EventDispatcher implements ISelectionModel, IRollOverModel
+ {
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function SingleSelectionIListModel()
+ {
+ }
+
+ private var _strand:IStrand;
+
+ /**
+ * @copy org.apache.royale.core.IBead#strand
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function set strand(value:IStrand):void
+ {
+ _strand = value;
+ }
+
+ private var _dataProvider:IList;
+
+ /**
+ * @copy org.apache.royale.core.ISelectionModel#dataProvider
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function get dataProvider():Object
+ {
+ return _dataProvider;
+ }
+
+ /**
+ * @private
+ * @royaleignorecoercion org.apache.royale.collections.IList
+ */
+ public function set dataProvider(value:Object):void
+ {
+ if (value == _dataProvider) return;
+
+ _dataProvider = value as IList;
+ if(!_dataProvider || _selectedIndex >= _dataProvider.length)
+ _selectedIndex = -1;
+
+ _selectedItem = _selectedIndex == -1 ? null : _dataProvider.getItemAt(_selectedIndex);
+
+ dispatchEvent(new Event("dataProviderChanged"));
+ }
+
+ private var _selectedIndex:int = -1;
+ private var _rollOverIndex:int = -1;
+ private var _labelField:String = null;
+
+ /**
+ * @copy org.apache.royale.core.ISelectionModel#labelField
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function get labelField():String
+ {
+ return _labelField;
+ }
+
+ /**
+ * @private
+ */
+ public function set labelField(value:String):void
+ {
+ if (value != _labelField) {
+ _labelField = value;
+ dispatchEvent(new Event("labelFieldChanged"));
+ }
+ }
+
+ /**
+ * @copy org.apache.royale.core.ISelectionModel#selectedIndex
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function get selectedIndex():int
+ {
+ return _selectedIndex;
+ }
+
+ /**
+ * @private
+ */
+ public function set selectedIndex(value:int):void
+ {
+ if (value == _selectedIndex) return;
+
+ _selectedIndex = value;
+ _selectedItem = (value == -1 || _dataProvider == null) ? null : (value < _dataProvider.length) ? _dataProvider.getItemAt(value) : null;
+ dispatchEvent(new Event("selectedIndexChanged"));
+ }
+
+ /**
+ * @copy org.apache.royale.core.IRollOverModel#rollOverIndex
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function get rollOverIndex():int
+ {
+ return _rollOverIndex;
+ }
+
+ /**
+ * @private
+ */
+ public function set rollOverIndex(value:int):void
+ {
+ if (value != _rollOverIndex) {
+ _rollOverIndex = value;
+ dispatchEvent(new Event("rollOverIndexChanged"));
+ }
+ }
+
+ private var _selectedItem:Object;
+
+ /**
+ * @copy org.apache.royale.core.ISelectionModel#selectedItem
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function get selectedItem():Object
+ {
+ return _selectedItem;
+ }
+
+ /**
+ * @private
+ */
+ public function set selectedItem(value:Object):void
+ {
+ if (value == _selectedItem) return;
+
+ _selectedItem = value;
+ var n:int = _dataProvider.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ if (_dataProvider.getItemAt(i) == value)
+ {
+ _selectedIndex = i;
+ break;
+ }
+ }
+ dispatchEvent(new Event("selectedItemChanged"));
+ dispatchEvent(new Event("selectedIndexChanged"));
+ }
+
+ private var _selectedString:String;
+
+ /**
+ * An alternative to selectedItem for strongly typing the
+ * the selectedItem if the Array is an Array of Strings.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 0.9
+ */
+ public function get selectedString():String
+ {
+ return String(_selectedItem);
+ }
+
+ /**
+ * @private
+ */
+ public function set selectedString(value:String):void
+ {
+ _selectedString = value;
+ var n:int = _dataProvider.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ if (String(_dataProvider.getItemAt(i)) == value)
+ {
+ _selectedIndex = i;
+ break;
+ }
+ }
+ dispatchEvent(new Event("selectedItemChanged"));
+ dispatchEvent(new Event("selectedIndexChanged"));
+ }
+ }
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListBase.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListBase.as
index 97e9f02..5e6e40a 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListBase.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListBase.as
@@ -25,10 +25,11 @@ COMPILE::JS
import mx.core.EdgeMetrics;
import mx.core.IFactory;
+import mx.core.IUIComponent;
import mx.core.ScrollPolicy;
import mx.core.UIComponent;
-import mx.core.IUIComponent;
import mx.core.mx_internal;
+import mx.utils.UIDUtil;
import org.apache.royale.core.ContainerBaseStrandChildren;
import org.apache.royale.core.IBeadLayout;
@@ -37,8 +38,8 @@ import org.apache.royale.core.IContainer;
import org.apache.royale.core.IContainerBaseStrandChildrenHost;
import org.apache.royale.core.IDataProviderItemRendererMapper;
import org.apache.royale.core.IItemRendererClassFactory;
-import org.apache.royale.core.ILayoutHost;
import org.apache.royale.core.ILayoutChild;
+import org.apache.royale.core.ILayoutHost;
import org.apache.royale.core.ILayoutParent;
import org.apache.royale.core.ILayoutView;
import org.apache.royale.core.IParent;
@@ -1055,5 +1056,49 @@ use namespace mx_internal;
// o.left + o.right;
}
}
+
+ /**
+ * Determines the UID for a data provider item. All items
+ * in a data provider must either have a unique ID (UID)
+ * or one will be generated and associated with it. This
+ * means that you cannot have an object or scalar value
+ * appear twice in a data provider.
+ *
+ * <p>For example, the following
+ * data provider is not supported because the value "foo"
+ * appears twice and the UID for a string is the string itself:</p>
+ *
+ * <pre>var sampleDP:Array = ["foo", "bar", "foo"]</pre>
+ *
+ * <p>Simple dynamic objects can appear twice if they are two
+ * separate instances. The following is supported because
+ * each of the instances will be given a different UID because
+ * they are different objects:</p>
+ *
+ * <pre>var sampleDP:Array = [{label: "foo"}, {label: "foo"}]</pre>
+ *
+ * <p>Note that the following is not supported because the same instance
+ * appears twice.</p>
+ *
+ * <pre>
+ * var foo:Object = {label: "foo"};
+ * sampleDP:Array = [foo, foo];</pre>
+ *
+ * @param data The data provider item.
+ *
+ * @return The UID as a string.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function itemToUID(data:Object):String
+ {
+ if (data == null)
+ return "null";
+ return UIDUtil.getUID(data);
+ }
+
}
}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/treeClasses/DefaultDataDescriptor.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/treeClasses/DefaultDataDescriptor.as
new file mode 100644
index 0000000..06485bd
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/treeClasses/DefaultDataDescriptor.as
@@ -0,0 +1,779 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.controls.treeClasses
+{
+
+import mx.collections.ArrayCollection;
+import mx.collections.CursorBookmark;
+import mx.collections.ICollectionView;
+import mx.collections.IList;
+import mx.collections.IViewCursor;
+import mx.collections.XMLListCollection;
+//import mx.controls.menuClasses.IMenuDataDescriptor;
+import mx.core.mx_internal;
+import org.apache.royale.utils.UIDUtil;
+
+use namespace mx_internal;
+
+/**
+ * The DefaultDataDescriptor class provides a default implementation for
+ * accessing and manipulating data for use in controls such as Tree and Menu.
+ *
+ * This implementation handles e4x XML and object nodes in similar but different
+ * ways. See each method description for details on how the method
+ * accesses values in nodes of various types.
+ *
+ * This class is the default value of the Tree, Menu, MenuBar, and
+ * PopUpMenuButton control <code>dataDescriptor</code> properties.
+ *
+ * @see mx.controls.treeClasses.ITreeDataDescriptor
+ * @see mx.controls.menuClasses.IMenuDataDescriptor
+ * @see mx.controls.Menu
+ * @see mx.controls.MenuBar
+ * @see mx.controls.PopUpMenuButton
+ * @see mx.controls.Tree
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class DefaultDataDescriptor implements ITreeDataDescriptor2 //, IMenuDataDescriptor
+{
+ include "../../core/Version.as";
+
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function DefaultDataDescriptor()
+ {
+ super();
+ }
+
+ /**
+ * @private
+ */
+ private var ChildCollectionCache:CollectionCache = new CollectionCache();
+
+ /**
+ * Provides access to a node's children. Returns a collection
+ * of children if they exist. If the node is an Object, the method
+ * returns the contents of the object's <code>children</code> field as
+ * an ArrayCollection.
+ * If the node is XML, the method returns an XMLListCollection containing
+ * the child elements.
+ *
+ * @param node The node object currently being evaluated.
+ * @param model The collection that contains the node; ignored by this class.
+ * @return An object containing the children nodes.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function getChildren(node:Object, model:Object = null):ICollectionView
+ {
+ if (node == null)
+ return null;
+
+ var children:*;
+ var childrenCollection:ICollectionView;
+
+ //first get the children based on the type of node.
+ if (node is XML)
+ {
+ //trace("getChildren", node.toXMLString());
+ children = node.*;
+ }
+ else if (node is Object)
+ {
+ //we'll try the default children property
+ try
+ {
+ children = node.children;
+ }
+ catch(e:Error)
+ {
+ }
+ }
+
+ //no children exist for this node
+ if (children == undefined && !(children is XMLList))
+ return null;
+
+ //then wrap children in ICollectionView if necessary
+ if (children is ICollectionView)
+ {
+ childrenCollection = ICollectionView(children);
+ }
+ else if (children is Array)
+ {
+ var oldArrayCollection:ArrayCollection = ChildCollectionCache.fetch(node);
+ if (!oldArrayCollection)
+ {
+ childrenCollection = new ArrayCollection(children);
+ ChildCollectionCache.put(node, childrenCollection);
+ }
+ else
+ {
+ childrenCollection = oldArrayCollection;
+ ArrayCollection(childrenCollection).dispatchResetEvent = false;
+ ArrayCollection(childrenCollection).source = children;
+ }
+
+ }
+ else if (children is XMLList)
+ {
+ var oldXMLCollection:XMLListCollection = ChildCollectionCache.fetch(node);
+ if (!oldXMLCollection)
+ {
+ // double check since XML as dictionary keys is inconsistent
+ for each (var p:* in ChildCollectionCache.keys)
+ {
+ if (p === node)
+ {
+ oldXMLCollection = ChildCollectionCache.fetch(p);
+ break;
+ }
+ }
+ }
+
+ if (!oldXMLCollection)
+ {
+ childrenCollection = new XMLListCollection(children);
+ ChildCollectionCache.put(node, childrenCollection);
+ }
+ else
+ {
+ childrenCollection = oldXMLCollection;
+
+ //We don't want to send a RESET type of collectionChange event in this case.
+ XMLListCollection(childrenCollection).dispatchResetEvent = false;
+ XMLListCollection(childrenCollection).source = children;
+ }
+ }
+ else
+ {
+ var childArray:Array = new Array(children);
+ if (childArray != null)
+ {
+ childrenCollection = new ArrayCollection(childArray);
+ }
+ }
+ return childrenCollection;
+ }
+
+ /**
+ * Determines if the node actually has children.
+ *
+ * @param node The node object currently being evaluated.
+ * @param model The collection that contains the node; ignored by this class.
+ *
+ * @return <code>true</code> if this node currently has children.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function hasChildren(node:Object, model:Object = null):Boolean
+ {
+ if (node == null)
+ return false;
+
+ //This default impl can't optimize this call to getChildren
+ //since we can't make any assumptions by type. Custom impl's
+ //can probably avoid this call and reduce the number of calls to
+ //getChildren if need be.
+ var children:ICollectionView = getChildren(node, model);
+ try
+ {
+ if (children.length > 0)
+ return true;
+ }
+ catch(e:Error)
+ {
+ }
+ return false;
+ }
+
+ /**
+ * Tests a node for termination.
+ * Branches are non-terminating but are not required to have any leaf nodes.
+ * If the node is XML, returns <code>true</code> if the node has children
+ * or a <code>true isBranch</code> attribute.
+ * If the node is an object, returns <code>true</code> if the node has a
+ * (possibly empty) <code>children</code> field.
+ *
+ * @param node The node object currently being evaluated.
+ * @param model The collection that contains the node; ignored by this class.
+ *
+ * @return <code>true</code> if this node is non-terminating.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function isBranch(node:Object, model:Object = null):Boolean
+ {
+ if (node == null)
+ return false;
+
+ var branch:Boolean = false;
+
+ if (node is XML)
+ {
+ var childList:XMLList = node.children();
+ //accessing non-required e4x attributes is quirky
+ //but we know we'll at least get an XMLList
+ var branchFlag:XMLList = node.@isBranch;
+ //check to see if a flag has been set
+ if (branchFlag.length() == 1)
+ {
+ //check flag and return (this flag overrides termination status)
+ if (branchFlag[0] == "true")
+ branch = true;
+ }
+ //since no flags, we'll check to see if there are children
+ else if (childList.length() != 0)
+ {
+ branch = true;
+ }
+ }
+ else if (node is Object)
+ {
+ try
+ {
+ if (node.children != undefined)
+ {
+ branch = true;
+ }
+ }
+ catch(e:Error)
+ {
+ }
+ }
+ return branch;
+ }
+
+ /**
+ * Returns a node's data.
+ * Currently returns the entire node.
+ *
+ * @param node The node object currently being evaluated.
+ * @param model The collection that contains the node; ignored by this class.
+ * @return The node.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function getData(node:Object, model:Object = null):Object
+ {
+ return Object(node);
+ }
+
+ /**
+ * Add a child node to a node at the specified index.
+ * This implementation does the following:
+ *
+ * <ul>
+ * <li>If the <code>parent</code> parameter is null or undefined,
+ * inserts the <code>child</code> parameter at the
+ * specified index in the collection specified by <code>model</code>
+ * parameter.
+ * </li>
+ * <li>If the <code>parent</code> parameter has a <code>children</code>
+ * field or property, the method adds the <code>child</code> parameter
+ * to it at the <code>index</code> parameter location.
+ * In this case, the <code>model</code> parameter is not required.
+ * </li>
+ * <li>If the <code>parent</code> parameter does not have a <code>children</code>
+ * field or property, the method adds the <code>children</code>
+ * property to the <code>parent</code>. The method then adds the
+ * <code>child</code> parameter to the parent at the
+ * <code>index</code> parameter location.
+ * In this case, the <code>model</code> parameter is not required.
+ * </li>
+ * <li>If the <code>index</code> value is greater than the collection
+ * length or number of children in the parent, adds the object as
+ * the last child.
+ * </li>
+ * </ul>
+ *
+ * @param parent The node object that will parent the child.
+ * @param newChild The node object that will be parented by the node.
+ * @param index The 0-based index of where to put the child node relative to the parent.
+ * @param model The entire collection that this node is a part of.
+ *
+ * @return <code>true</code> if successful.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function addChildAt(parent:Object, newChild:Object, index:int, model:Object = null):Boolean
+ {
+ if (!parent)
+ {
+ try
+ {
+ if (index > model.length)
+ index = model.length;
+ if (model is IList)
+ IList(model).addItemAt(newChild, index);
+ else
+ {
+ var cursor:IViewCursor = model.createCursor();
+ cursor.seek(CursorBookmark.FIRST, index);
+ cursor.insert(newChild);
+ }
+
+ return true;
+ }
+ catch(e:Error)
+ {
+ }
+ }
+ else
+ {
+ var children:ICollectionView = ICollectionView(getChildren(parent, model));
+ if (!children)
+ {
+ if (parent is XML)
+ {
+ var temp:XMLList = new XMLList();
+ XML(parent).appendChild(temp);
+ children = new XMLListCollection(parent.children());
+ }
+ else if (parent is Object)
+ {
+ parent.children = new ArrayCollection();
+ children = parent.children;
+ }
+ }
+ try
+ {
+ if (index > children.length)
+ index = children.length;
+ if (children is IList)
+ IList(children).addItemAt(newChild, index);
+ else
+ {
+ cursor = children.createCursor();
+ cursor.seek(CursorBookmark.FIRST, index);
+ cursor.insert(newChild);
+ }
+ return true;
+ }
+ catch(e:Error)
+ {
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Removes the child node from a node at the specified index.
+ * If the <code>parent</code> parameter is null
+ * or undefined, the method uses the <code>model</code> parameter to
+ * access the child; otherwise, it uses the <code>parent</code> parameter
+ * and ignores the <code>model</code> parameter.
+ *
+ * @param parent The node object that currently parents the child node.
+ * @param child The node that is being removed.
+ * @param index The 0-based index of the child node to remove relative to the parent.
+ * @param model The entire collection that this node is a part of.
+ *
+ * @return <code>true</code> if successful.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function removeChildAt(parent:Object, child:Object, index:int, model:Object = null):Boolean
+ {
+ //handle top level where there is no parent
+ if (!parent)
+ {
+ try
+ {
+ if (index > model.length)
+ index = model.length;
+ if (model is IList)
+ model.removeItemAt(index);
+ else
+ {
+ var cursor:IViewCursor = model.createCursor();
+ cursor.seek(CursorBookmark.FIRST, index);
+ cursor.remove();
+ }
+
+ return true;
+ }
+ catch(e:Error)
+ {
+ }
+ }
+ else
+ {
+ var children:ICollectionView = ICollectionView(getChildren(parent, model));
+ try
+ {
+ if (index > children.length)
+ index = children.length;
+ if (children is IList)
+ IList(children).removeItemAt(index);
+ else
+ {
+ cursor = children.createCursor();
+ cursor.seek(CursorBookmark.FIRST, index);
+ cursor.remove();
+ }
+
+ return true;
+ }
+ catch(e:Error)
+ {
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the type identifier of a node.
+ * This method is used by menu-based controls to determine if the
+ * node represents a separator, radio button,
+ * a check box, or normal item.
+ *
+ * @param node The node object for which to get the type.
+ *
+ * @return The value of the <code>type</code> attribute or field,
+ * or the empty string if there is no such field.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function getType(node:Object):String
+ {
+ if (node is XML)
+ {
+ return String(node.@type);
+ }
+ else if (node is Object)
+ {
+ try
+ {
+ return String(node.type);
+ }
+ catch(e:Error)
+ {
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Returns whether the node is enabled.
+ * This method is used by menu-based controls.
+ *
+ * @param node The node for which to get the status.
+ *
+ * @return The value of the node's <code>enabled</code>
+ * attribute or field, or <code>true</code> if there is no such
+ * entry or the value is not <code>false</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function isEnabled(node:Object):Boolean
+ {
+ var enabled:*;
+ if (node is XML)
+ {
+ enabled = node.@enabled;
+ if (enabled[0] == false)
+ return false;
+ }
+ else if (node is Object)
+ {
+ try
+ {
+ return !("false" == String(node.enabled))
+ }
+ catch(e:Error)
+ {
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Sets the value of the field or attribute in the data provider
+ * that identifies whether the node is enabled.
+ * This method sets the value of the node's <code>enabled</code>
+ * attribute or field.
+ * This method is used by menu-based controls.
+ *
+ * @param node The node for which to set the status.
+ * @param value Whether the node is enabled.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function setEnabled(node:Object, value:Boolean):void
+ {
+ if (node is XML)
+ {
+ node.@enabled = value;
+ }
+ else if (node is Object)
+ {
+ try
+ {
+ node.enabled = value;
+ }
+ catch(e:Error)
+ {
+ }
+ }
+ }
+
+ /**
+ * Returns whether the node is toggled.
+ * This method is used by menu-based controls.
+ *
+ * @param node The node for which to get the status.
+ *
+ * @return The value of the node's <code>toggled</code>
+ * attribute or field, or <code>false</code> if there is no such
+ * entry.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function isToggled(node:Object):Boolean
+ {
+ if (node is XML)
+ {
+ var toggled:* = node.@toggled;
+ if (toggled[0] == true)
+ return true;
+ }
+ else if (node is Object)
+ {
+ try
+ {
+ return Boolean(node.toggled);
+ }
+ catch(e:Error)
+ {
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Sets the value of the field or attribute in the data provider
+ * that identifies whether the node is toggled.
+ * This method sets the value of the node's <code>toggled</code>
+ * attribute or field.
+ * This method is used by menu-based controls.
+ *
+ * @param node The node for which to set the status.
+ * @param value Whether the node is toggled.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function setToggled(node:Object, value:Boolean):void
+ {
+ if (node is XML)
+ {
+ node.@toggled = value;
+ }
+ else if (node is Object)
+ {
+ try
+ {
+ node.toggled = value;
+ }
+ catch(e:Error)
+ {
+ }
+ }
... 3266 lines suppressed ...