1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef nsTreeContentView_h__
8 #define nsTreeContentView_h__
9 
10 #include "nsCycleCollectionParticipant.h"
11 #include "nsTArray.h"
12 #include "nsStubDocumentObserver.h"
13 #include "nsITreeView.h"
14 #include "nsITreeSelection.h"
15 #include "nsWrapperCache.h"
16 #include "mozilla/Attributes.h"
17 #include "mozilla/UniquePtr.h"
18 
19 class nsSelection;
20 class nsTreeColumn;
21 class Row;
22 
23 namespace mozilla {
24 class ErrorResult;
25 
26 namespace dom {
27 class DataTransfer;
28 class Document;
29 class Element;
30 class XULTreeElement;
31 }  // namespace dom
32 }  // namespace mozilla
33 
34 nsresult NS_NewTreeContentView(nsITreeView** aResult);
35 
36 class nsTreeContentView final : public nsITreeView,
37                                 public nsStubDocumentObserver,
38                                 public nsWrapperCache {
39   typedef mozilla::dom::Element Element;
40 
41  public:
42   nsTreeContentView(void);
43 
44   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
45   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsTreeContentView,
46                                                          nsITreeView)
47 
48   virtual JSObject* WrapObject(JSContext* aCx,
49                                JS::Handle<JSObject*> aGivenProto) override;
50   nsISupports* GetParentObject();
51 
RowCount()52   int32_t RowCount() { return mRows.Length(); }
GetSelection()53   nsITreeSelection* GetSelection() { return mSelection; }
54   void SetSelection(nsITreeSelection* aSelection, mozilla::ErrorResult& aError);
55   void GetRowProperties(int32_t aRow, nsAString& aProperties,
56                         mozilla::ErrorResult& aError);
57   void GetCellProperties(int32_t aRow, nsTreeColumn& aColumn,
58                          nsAString& aProperies, mozilla::ErrorResult& aError);
59   void GetColumnProperties(nsTreeColumn& aColumn, nsAString& aProperies);
60   bool IsContainer(int32_t aRow, mozilla::ErrorResult& aError);
61   bool IsContainerOpen(int32_t aRow, mozilla::ErrorResult& aError);
62   bool IsContainerEmpty(int32_t aRow, mozilla::ErrorResult& aError);
63   bool IsSeparator(int32_t aRow, mozilla::ErrorResult& aError);
IsSorted()64   bool IsSorted() { return false; }
65   bool CanDrop(int32_t aRow, int32_t aOrientation,
66                mozilla::dom::DataTransfer* aDataTransfer,
67                mozilla::ErrorResult& aError);
68   void Drop(int32_t aRow, int32_t aOrientation,
69             mozilla::dom::DataTransfer* aDataTransfer,
70             mozilla::ErrorResult& aError);
71   int32_t GetParentIndex(int32_t aRow, mozilla::ErrorResult& aError);
72   bool HasNextSibling(int32_t aRow, int32_t aAfterIndex,
73                       mozilla::ErrorResult& aError);
74   int32_t GetLevel(int32_t aRow, mozilla::ErrorResult& aError);
75   void GetImageSrc(int32_t aRow, nsTreeColumn& aColumn, nsAString& aSrc,
76                    mozilla::ErrorResult& aError);
77   void GetCellValue(int32_t aRow, nsTreeColumn& aColumn, nsAString& aValue,
78                     mozilla::ErrorResult& aError);
79   void GetCellText(int32_t aRow, nsTreeColumn& aColumn, nsAString& aText,
80                    mozilla::ErrorResult& aError);
81   void SetTree(mozilla::dom::XULTreeElement* aTree,
82                mozilla::ErrorResult& aError);
83   void ToggleOpenState(int32_t aRow, mozilla::ErrorResult& aError);
84   void CycleHeader(nsTreeColumn& aColumn, mozilla::ErrorResult& aError);
SelectionChanged()85   void SelectionChanged() {}
CycleCell(int32_t aRow,nsTreeColumn & aColumn)86   void CycleCell(int32_t aRow, nsTreeColumn& aColumn) {}
87   bool IsEditable(int32_t aRow, nsTreeColumn& aColumn,
88                   mozilla::ErrorResult& aError);
89   void SetCellValue(int32_t aRow, nsTreeColumn& aColumn,
90                     const nsAString& aValue, mozilla::ErrorResult& aError);
91   void SetCellText(int32_t aRow, nsTreeColumn& aColumn, const nsAString& aText,
92                    mozilla::ErrorResult& aError);
93   Element* GetItemAtIndex(int32_t aRow, mozilla::ErrorResult& aError);
94   int32_t GetIndexOfItem(Element* aItem);
95 
96   NS_DECL_NSITREEVIEW
97 
98   // nsIDocumentObserver
99   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
100   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
101   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
102   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
103   NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
104 
105   static bool CanTrustTreeSelection(nsISupports* aValue);
106 
107  protected:
108   ~nsTreeContentView(void);
109 
110   // Recursive methods which deal with serializing of nested content.
111   void Serialize(nsIContent* aContent, int32_t aParentIndex, int32_t* aIndex,
112                  nsTArray<mozilla::UniquePtr<Row>>& aRows);
113 
114   void SerializeItem(Element* aContent, int32_t aParentIndex, int32_t* aIndex,
115                      nsTArray<mozilla::UniquePtr<Row>>& aRows);
116 
117   void SerializeSeparator(Element* aContent, int32_t aParentIndex,
118                           int32_t* aIndex,
119                           nsTArray<mozilla::UniquePtr<Row>>& aRows);
120 
121   void GetIndexInSubtree(nsIContent* aContainer, nsIContent* aContent,
122                          int32_t* aResult);
123 
124   // Helper methods which we use to manage our plain array of rows.
125   int32_t EnsureSubtree(int32_t aIndex);
126 
127   int32_t RemoveSubtree(int32_t aIndex);
128 
129   int32_t InsertRow(int32_t aParentIndex, int32_t aIndex, nsIContent* aContent);
130 
131   void InsertRowFor(nsIContent* aParent, nsIContent* aChild);
132 
133   int32_t RemoveRow(int32_t aIndex);
134 
135   void ClearRows();
136 
137   void OpenContainer(int32_t aIndex);
138 
139   void CloseContainer(int32_t aIndex);
140 
141   int32_t FindContent(nsIContent* aContent);
142 
143   void UpdateSubtreeSizes(int32_t aIndex, int32_t aCount);
144 
145   void UpdateParentIndexes(int32_t aIndex, int32_t aSkip, int32_t aCount);
146 
147   bool CanDrop(int32_t aRow, int32_t aOrientation,
148                mozilla::ErrorResult& aError);
149   void Drop(int32_t aRow, int32_t aOrientation, mozilla::ErrorResult& aError);
150 
151   // Content helpers.
152   Element* GetCell(nsIContent* aContainer, nsTreeColumn& aCol);
153 
154  private:
155   bool IsValidRowIndex(int32_t aRowIndex);
156 
157   RefPtr<mozilla::dom::XULTreeElement> mTree;
158   nsCOMPtr<nsITreeSelection> mSelection;
159   nsCOMPtr<nsIContent> mBody;
160   mozilla::dom::Document* mDocument;  // WEAK
161   nsTArray<mozilla::UniquePtr<Row>> mRows;
162 };
163 
164 #endif  // nsTreeContentView_h__
165