michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: * michael@0: * This Original Code has been modified by IBM Corporation. michael@0: * Modifications made by IBM described herein are michael@0: * Copyright (c) International Business Machines michael@0: * Corporation, 2000 michael@0: * michael@0: * Modifications to Mozilla code or documentation michael@0: * identified per MPL Section 3.3 michael@0: * michael@0: * Date Modified by Description of modification michael@0: * 03/27/2000 IBM Corp. Added PR_CALLBACK for Optlink michael@0: * use in OS2 michael@0: */ michael@0: michael@0: /* michael@0: This sort service is used to sort template built content or content by attribute. michael@0: */ michael@0: michael@0: #ifndef nsXULTemplateResultSetRDF_h michael@0: #define nsXULTemplateResultSetRDF_h michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsCOMArray.h" michael@0: #include "nsTArray.h" michael@0: #include "nsIContent.h" michael@0: #include "nsIXULTemplateResult.h" michael@0: #include "nsIXULTemplateQueryProcessor.h" michael@0: #include "nsIXULSortService.h" michael@0: #include "nsCycleCollectionParticipant.h" michael@0: michael@0: enum nsSortState_direction { michael@0: nsSortState_descending, michael@0: nsSortState_ascending, michael@0: nsSortState_natural michael@0: }; michael@0: michael@0: // the sort state holds info about the current sort michael@0: struct nsSortState michael@0: { michael@0: bool initialized; michael@0: bool invertSort; michael@0: bool inbetweenSeparatorSort; michael@0: bool sortStaticsLast; michael@0: bool isContainerRDFSeq; michael@0: michael@0: uint32_t sortHints; michael@0: michael@0: nsSortState_direction direction; michael@0: nsAutoString sort; michael@0: nsCOMArray sortKeys; michael@0: michael@0: nsCOMPtr processor; michael@0: nsCOMPtr lastContainer; michael@0: bool lastWasFirst, lastWasLast; michael@0: michael@0: nsSortState() michael@0: : initialized(false), michael@0: sortHints(0) michael@0: { michael@0: } michael@0: void Traverse(nsCycleCollectionTraversalCallback &cb) const michael@0: { michael@0: cb.NoteXPCOMChild(processor); michael@0: cb.NoteXPCOMChild(lastContainer); michael@0: } michael@0: }; michael@0: michael@0: // information about a particular item to be sorted michael@0: struct contentSortInfo { michael@0: nsCOMPtr content; michael@0: nsCOMPtr parent; michael@0: nsCOMPtr result; michael@0: void swap(contentSortInfo& other) michael@0: { michael@0: content.swap(other.content); michael@0: parent.swap(other.parent); michael@0: result.swap(other.result); michael@0: } michael@0: }; michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: // ServiceImpl michael@0: // michael@0: // This is the sort service. michael@0: // michael@0: class XULSortServiceImpl : public nsIXULSortService michael@0: { michael@0: protected: michael@0: XULSortServiceImpl(void) {} michael@0: virtual ~XULSortServiceImpl(void) {} michael@0: michael@0: friend nsresult NS_NewXULSortService(nsIXULSortService** mgr); michael@0: michael@0: private: michael@0: michael@0: public: michael@0: // nsISupports michael@0: NS_DECL_ISUPPORTS michael@0: michael@0: // nsISortService michael@0: NS_DECL_NSIXULSORTSERVICE michael@0: michael@0: /** michael@0: * Set sort and sortDirection attributes when a sort is done. michael@0: */ michael@0: void michael@0: SetSortHints(nsIContent *aNode, nsSortState* aSortState); michael@0: michael@0: /** michael@0: * Set sortActive and sortDirection attributes on a tree column when a sort michael@0: * is done. The column to change is the one with a sort attribute that michael@0: * matches the sort key. The sort attributes are removed from the other michael@0: * columns. michael@0: */ michael@0: void michael@0: SetSortColumnHints(nsIContent *content, michael@0: const nsAString &sortResource, michael@0: const nsAString &sortDirection); michael@0: michael@0: /** michael@0: * Determine the list of items which need to be sorted. This is determined michael@0: * in the following way: michael@0: * - for elements that have a content builder, get its list of generated michael@0: * results michael@0: * - otherwise, for trees, get the child treeitems michael@0: * - otherwise, get the direct children michael@0: */ michael@0: nsresult michael@0: GetItemsToSort(nsIContent *aContainer, michael@0: nsSortState* aSortState, michael@0: nsTArray& aSortItems); michael@0: michael@0: /** michael@0: * Get the list of items to sort for template built content michael@0: */ michael@0: nsresult michael@0: GetTemplateItemsToSort(nsIContent* aContainer, michael@0: nsIXULTemplateBuilder* aBuilder, michael@0: nsSortState* aSortState, michael@0: nsTArray& aSortItems); michael@0: michael@0: /** michael@0: * Sort a container using the supplied sort state details. michael@0: */ michael@0: nsresult michael@0: SortContainer(nsIContent *aContainer, nsSortState* aSortState); michael@0: michael@0: /** michael@0: * Given a list of sortable items, reverse the list. This is done michael@0: * when simply changing the sort direction for the same key. michael@0: */ michael@0: nsresult michael@0: InvertSortInfo(nsTArray& aData, michael@0: int32_t aStart, int32_t aNumItems); michael@0: michael@0: /** michael@0: * Initialize sort information from attributes specified on the container, michael@0: * the sort key and sort direction. michael@0: * michael@0: * @param aRootElement the element that contains sort attributes michael@0: * @param aContainer the container to sort, usually equal to aRootElement michael@0: * @param aSortKey space separated list of sort keys michael@0: * @param aSortDirection direction to sort in michael@0: * @param aSortState structure filled in with sort data michael@0: */ michael@0: static nsresult michael@0: InitializeSortState(nsIContent* aRootElement, michael@0: nsIContent* aContainer, michael@0: const nsAString& aSortKey, michael@0: const nsAString& aSortDirection, michael@0: nsSortState* aSortState); michael@0: michael@0: /** michael@0: * Compares aLeft and aRight and returns < 0, 0, or > 0. The sort michael@0: * hints are checked for case matching and integer sorting. michael@0: */ michael@0: static int32_t CompareValues(const nsAString& aLeft, michael@0: const nsAString& aRight, michael@0: uint32_t aSortHints); michael@0: }; michael@0: michael@0: #endif