File: SourceListModel.java

package info (click to toggle)
mac-widgets 0.10.0%2Bsvn416-dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,968 kB
  • ctags: 2,003
  • sloc: java: 9,909; makefile: 13; sh: 12
file content (293 lines) | stat: -rw-r--r-- 11,539 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
package com.explodingpixels.macwidgets;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * The backing model to be used with a {@link SourceList}.
 */
public final class SourceListModel {

    private List<SourceListCategory> fCategories = new ArrayList<SourceListCategory>();
    private List<SourceListModelListener> fListeners = new ArrayList<SourceListModelListener>();
    private PropertyChangeListener fPropertyChangeListener = createSourceListItemListener();

    // SourceListCategory methods /////////////////////////////////////////////////////////////////

    /**
     * Gets the {@link SourceListCategory}s associated with this model.
     *
     * @return the {@link SourceListCategory}s associated with this model.
     */
    public List<SourceListCategory> getCategories() {
        return Collections.unmodifiableList(fCategories);
    }

    /**
     * Adds the given category to the model and fires an event such that
     * {@link SourceListModelListener}s will be notified.
     *
     * @param category the {@link SourceListCategory} to add.
     */
    public void addCategory(SourceListCategory category) {
        addCategory(category, fCategories.size());
    }

    /**
     * Adds the given category to the model at the given index and fires an event such that
     * {@link SourceListModelListener}s will be notified.
     *
     * @param category the {@link com.explodingpixels.macwidgets.SourceListCategory} to add.
     * @param index    the index to add the category at.
     */
    public void addCategory(SourceListCategory category, int index) {
        fCategories.add(index, category);
        fireCategoryAdded(category, index);
    }

    /**
     * Removes the given category from the model and fires an event such that
     * {@link SourceListModelListener}s will be notified.
     *
     * @param category the {@link SourceListCategory} to remove.
     * @throws IllegalArgumentException if the given category is not part of this model.
     */
    public void removeCategory(SourceListCategory category) {
        boolean removed = fCategories.remove(category);
        if (!removed) {
            throw new IllegalArgumentException("The given category does not exist in this model.");
        }
        fireCategoryRemoved(category);
    }

    /**
     * Removes the category at the given index from the model and fires an event such that
     * {@link SourceListModelListener}s will be notified.
     *
     * @param index the index of the {@link SourceListCategory} to remove.
     * @throws IllegalArgumentException if there is no category at the given index.
     */
    public void removeCategoryAt(int index) {
        SourceListCategory category = fCategories.remove(index);
        if (category == null) {
            throw new IllegalArgumentException("There is no category at the index " + index + ".");
        }
        fireCategoryRemoved(category);
    }

    // SourceListItem methods /////////////////////////////////////////////////////////////////////

    /**
     * Adds the given item to the given {@link SourceListCategory}.
     *
     * @param item     the item to add.
     * @param category the category to add the item to.
     * @throws IllegalStateException if the given category is not in the model.
     */
    public void addItemToCategory(SourceListItem item, SourceListCategory category) {
        addItemToCategory(item, category, category.getItemCount());
    }

    /**
     * Adds the given item to the given {@link SourceListCategory} at the given index within that
     * category.
     *
     * @param item     the item to add.
     * @param category the category to add the item to.
     * @param index    the index in the category to add the item.
     * @throws IllegalStateException if the given category is not in the model.
     */
    public void addItemToCategory(SourceListItem item, SourceListCategory category, int index) {
        validateCategoryIsInModel(category);
        category.addItem(index, item);
        item.addPropertyChangeListener(fPropertyChangeListener);
        fireItemAddedToCategory(item, category, index);
    }

    /**
     * Adds the given "child" item to the given "parent" item.
     *
     * @param childItem  the item to add to the given parent item.
     * @param parentItem the item to add the child item to.
     * @throws IllegalStateException if the given parent item is not in the model.
     */
    public void addItemToItem(SourceListItem childItem, SourceListItem parentItem) {
        addItemToItem(childItem, parentItem, parentItem.getChildItems().size());
    }

    /**
     * Adds the given "child" item to the given "parent" item at the given index. The
     * parent {@link SourceListItem} will be expanded if it was not a parent but becomes a parent
     * as a result of this call.
     *
     * @param childItem  the item to add to the given parent item.
     * @param parentItem the item to add the child item to.
     * @param index      the index of the parent item at which to add the child item.
     * @throws IllegalStateException if the given child or parent item is not in the model.
     */
    public void addItemToItem(SourceListItem childItem, SourceListItem parentItem, int index) {
        validateItemIsInModel(parentItem);
        parentItem.addItem(index, childItem);
        childItem.addPropertyChangeListener(fPropertyChangeListener);
        fireItemAddedToItem(childItem, parentItem, index);
    }

    /**
     * Removes the given item from the given category.
     *
     * @param item     the item to remove from the given category.
     * @param category the category form which to remove the given item.
     * @throws IllegalStateException if the given category is not in the model.
     */
    public void removeItemFromCategory(SourceListItem item, SourceListCategory category) {
        validateItemIsInModel(item);
        validateCategoryIsInModel(category);
        category.removeItem(item);
        item.removePropertyChangeListener(fPropertyChangeListener);
        fireItemRemovedFromCategory(item, category);
    }

    /**
     * Removes the item at the given index from the given category.
     *
     * @param category the category from which to remove the item.
     * @param index    the index of the item to remove.
     * @throws IllegalStateException if the given category is not in the model.
     */
    public void removeItemFromCategoryAtIndex(SourceListCategory category, int index) {
        removeItemFromCategory(category.getItem(index), category);
    }

    /**
     * Removes the given child item at from the given parent item.
     *
     * @param childItem  the item to remove.
     * @param parentItem the item from which to remove the given child item.
     * @throws IllegalStateException if the given child or parent item is not in the model.
     */
    public void removeItemFromItem(SourceListItem childItem, SourceListItem parentItem) {
        validateItemIsInModel(childItem);
        validateItemIsInModel(parentItem);
        parentItem.removeItem(childItem);
        childItem.removePropertyChangeListener(fPropertyChangeListener);
        fireItemRemovedFromItem(childItem, parentItem);
    }

    /**
     * Removes the given child item at from the given parent item.
     *
     * @param parentItem the item from which to remove the given child item.
     * @param index      the index of the item to remove.
     * @throws IllegalStateException if the given child or parent item is not in the model.
     */
    public void removeItemFromItem(SourceListItem parentItem, int index) {
        validateItemIsInModel(parentItem);
        SourceListItem itemRemoved = parentItem.removeItem(index);
        fireItemRemovedFromItem(itemRemoved, parentItem);
    }

    // Utility methods. ///////////////////////////////////////////////////////////////////////////

    private PropertyChangeListener createSourceListItemListener() {
        return new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent event) {
                SourceListItem item = (SourceListItem) event.getSource();
                fireItemChanged(item);
            }
        };
    }

    private void validateCategoryIsInModel(SourceListCategory category) {
        if (!fCategories.contains(category)) {
            throw new IllegalArgumentException(
                    "The " + category.getText() + " category is not part of this model.");
        }
    }

    /**
     * Checks if the given {@link SourceListItem} is in this model.
     *
     * @param item the item to check if is in this model.
     * @throws IllegalArgumentException if the given item is not part of this model.
     */
    public void validateItemIsInModel(SourceListItem item) {
        boolean found = false;
        for (SourceListCategory category : fCategories) {
            found = category.containsItem(item);
            if (found) {
                break;
            }
        }
        if (!found) {
            throw new IllegalArgumentException("The given item is not part of this model.");
        }
    }

    // SourceListModelListener support. ///////////////////////////////////////////////////////////

    private void fireCategoryAdded(SourceListCategory category, int index) {
        for (SourceListModelListener listener : fListeners) {
            listener.categoryAdded(category, index);
        }
    }

    private void fireCategoryRemoved(SourceListCategory category) {
        for (SourceListModelListener listener : fListeners) {
            listener.categoryRemoved(category);
        }
    }

    private void fireItemAddedToCategory(SourceListItem item, SourceListCategory category, int index) {
        for (SourceListModelListener listener : fListeners) {
            listener.itemAddedToCategory(item, category, index);
        }
    }

    private void fireItemRemovedFromCategory(SourceListItem item,
                                             SourceListCategory category) {
        for (SourceListModelListener listener : fListeners) {
            listener.itemRemovedFromCategory(item, category);
        }
    }

    private void fireItemAddedToItem(SourceListItem childItem, SourceListItem parentItem, int index) {
        for (SourceListModelListener listener : fListeners) {
            listener.itemAddedToItem(childItem, parentItem, index);
        }
    }

    private void fireItemRemovedFromItem(SourceListItem childItem,
                                         SourceListItem parentItem) {
        for (SourceListModelListener listener : fListeners) {
            listener.itemRemovedFromItem(childItem, parentItem);
        }
    }

    private void fireItemChanged(SourceListItem item) {
        for (SourceListModelListener listener : fListeners) {
            listener.itemChanged(item);
        }
    }

    /**
     * Adds the given {@link SourceListModelListener} to the list of listeners.
     *
     * @param listener the listener to add.
     */
    public void addSourceListModelListener(SourceListModelListener listener) {
        fListeners.add(listener);
    }

    /**
     * Removes the given {@link SourceListModelListener} from the list of listeners.
     *
     * @param listener the listener to remove.
     */
    public void removeSourceListModelListener(SourceListModelListener listener) {
        fListeners.remove(listener);
    }

}