//////////////////////////////////////////////////////////////////////////////// // // 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 spark.collections { import flash.events.Event; import mx.styles.IAdvancedStyleClient; import mx.collections.ISortField; import mx.core.FlexGlobals; import mx.core.IFlexModule; import mx.core.IMXMLObject; import mx.utils.ObjectUtil; import spark.globalization.SortingCollator; [ResourceBundle("collections")] //-------------------------------------- // Styles //-------------------------------------- /** * The locale identifier that specifies the language, region, script * and optionally other related tags and keys. * The syntax of this identifier must follow the syntax defined * by the Unicode Technical Standard #35 (for example, en-US, de-DE, zh-Hans-CN). * *
For browser based apps, the default locale is based on the language settings from the browser. * (Note that this is not the browser UI language that is available from Javascript, but rather is the list of * preferred locales for web pages that the user has set in the browser preferences.) For AIR applications, * the default UI locale is based on the user's system preferences.
* * @see http://www.unicode.org/reports/tr35/ * * @langversion 3.0 * @playerversion Flash 10.1 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ [Style(name="locale", type="String", inherit="yes")] /** * 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: * *
* var col:ICollectionView = new ArrayCollection();
* col.addItem({first:"Anders", last:"Dickerson"});
* var sort:Sort = new Sort();
* var sortfield:SortField = new SortField("first", true);
* sortfield.setStyle("locale", "en-US");
* sort.fields = [sortfield];
* col.sort = sort;
*
*
* There are situations in which the collection contains simple items, like
* String
, Date
, Boolean
, 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 name
specified.
* For example:
*
*
* var col:ICollectionView = new ArrayCollection();
* col.addItem("California");
* col.addItem("Arizona");
* var sort:Sort = new Sort();
* var sortfield:SortField = new SortField(null, true);
* sortfield.setStyle("locale", "en-US");
* sort.fields = [sortfield];
* col.sort = sort;
*
*
* The default comparison provided by the SortField
class
* provides correct language specific
* sorting for strings. The language is selected by the setting the locale
* style on an instance of the class in one of the following ways:
*
* <fx:Declarations>*
* <s:SortField id="sf" />
* </fx:Declarations> *
* <fx:Declarations>*
* <s:SortField id="sf_SimplifiedChinese" locale="zh-Hans-CN" />
* </fx:Declarations> *
setStyle
method,
* e.g. sf.setStyle("locale", "zh-Hans-CN")
* UIComponent
by calling the
* UIComponent's addStyleClient()
method.
* The <s:SortField>
tag has the following attributes:
* <s:SortField * Properties * compareFunction="Internal compare function" * descending="false" * name="null" * numeric="null" * /> ** * @includeExample examples/SortExample1.mxml * @includeExample examples/SortExample2.mxml * * @see mx.collections.ICollectionView * @see spark.collections.Sort * * @langversion 3.0 * @playerversion Flash 10.1 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public class SortField extends mx.collections.SortField implements IAdvancedStyleClient, IFlexModule, IMXMLObject { include "../core/Version.as"; include "AdvancedStyleClientImplementation.as"; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @param name The name of the property that this field uses for * comparison. * If the object is a simple type, pass
null
.
* @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 10.1
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function SortField(name:String = null,
descending:Boolean = false,
numeric:Object = null,
sortCompareType:String = null,
customCompareFunction:Function = null)
{
super(name, false, descending, numeric, sortCompareType, customCompareFunction);
initAdvancedStyleClient();
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
* Cache for "locale" style.
*
* The code needs be able to find out if the locale style has been changed
* from earlier.
*/
private var localeStyle:* = undefined;
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
[Inspectable(category="General")]
/**
* The function that compares two items during a sort of items for the
* associated collection. If you specify a compareFunction
* property in an ISort
object, Flex ignores any
* compareFunction
properties of the ISort's
* SortField
objects.
*
* The compare function must have the following signature:
* *function myCompare(a:Object, b:Object):int
This function must return the following values:
* *Object a
should appear before the
* Object b
in the sorted sequenceObject a
equals the
* Object b
Object a
should appear after the
* Object b
in the sorted sequenceThe default value is an internal compare function that can perform
* a string, numeric, or date comparison in ascending or descending order.
* The string comparison is performed using the locale (language,
* region and script) specific comparison method from the
* SortingCollator
class.
* This class uses the locale style to determine a locale.
* 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.
styleChanged()
method,
* passing to it the name of the style being set.
*
* For the Collator class this method determines whether or not the
* locale style has changed and if needed updates the instance of
* the class to reflect this change. If the locale has been
* updated the change
event will be dispatched and
* uses of the bindable methods or properties will be updated.
*
* Called by AdvancedStyleClientImplementation.as
*
* @param styleProp The name of the style property, or null if
* all styles for this component have changed.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
private function _styleChanged(styleProp:String):void
{
localeChanged();
_advancedStyleClient.styleChangedImpl(styleProp);
}
//--------------------------------------------------------------------------
//
// Private Properties
//
//--------------------------------------------------------------------------
//---------------------------------
// stringCollator
//---------------------------------
/**
* @private
* Locale-aware string collator.
*/
private var internalStringCollator:SortingCollator;
/**
* @private
* Locale-aware string collator
*
* @default false
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
private function get stringCollator():SortingCollator
{
if (!internalStringCollator)
{
ensureStyleSource();
const locale:* = getStyle("locale");
internalStringCollator = new SortingCollator();
internalStringCollator.setStyle("locale", locale);
}
return internalStringCollator;
}
//--------------------------------------------------------------------------
//
// Private Methods
//
//--------------------------------------------------------------------------
/**
* @private
* Ensure some style source exists for this instance of a globalization
* object.
*
* A style source is considered exist if (A) styleParent value is non-null,
* or (B) localeStyle value has some useable value.
* If neither is the case, this style client will be added to the
* FlexGlobals.topLevelApplication as a child if possible.
*
* As a side effect this will call the styleChanged method and if the
* locale has changed will cause the createWorkingInstance method
* to be called.
*/
private function ensureStyleSource():void
{
if (!styleParent &&
((localeStyle === undefined) || (localeStyle === null)))
{
if (FlexGlobals.topLevelApplication)
{
FlexGlobals.topLevelApplication.addStyleClient(this);
}
}
}
/**
* Pull the strings from the objects and call the implementation.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
override 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 stringCollator.compare(fa, fb);
}
/**
* 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 10.1
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
override 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 stringCollator.compare(sa, sb);
}
}
/**
* @private
* This method is called if a style is changed on the instances of
* this formatter.
*
* This method determines if the locale style has changed and if
* so it updates the formatter to reflect this change.
* If the locale has been updated the change
event
* will be dispatched and uses of the
* bindable methods or properties will be updated.
*/
private function localeChanged():void
{
const newLocaleStyle:* = _advancedStyleClient.getStyleImpl("locale");
if (localeStyle === newLocaleStyle)
return;
localeStyle = newLocaleStyle;
if (internalStringCollator)
{
internalStringCollator.setStyle("locale", localeStyle);
}
dispatchEvent(new Event(Event.CHANGE));
}
}
}