1/*
2 * Copyright 2006, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Stephan Aßmus <superstippi@gmx.de>
7 */
8
9#include "Selection.h"
10
11#include <stdio.h>
12
13#include <debugger.h>
14
15#include "Selectable.h"
16
17// constructor
18Selection::Selection()
19	: fSelected(20)
20{
21}
22
23// destructor
24Selection::~Selection()
25{
26}
27
28// Select
29bool
30Selection::Select(Selectable* object, bool extend)
31{
32	AutoNotificationSuspender _(this);
33
34	if (!extend)
35		_DeselectAllExcept(object);
36
37	bool success = false;
38
39	if (!object->IsSelected()) {
40
41		#if DEBUG
42		if (fSelected.HasItem((void*)object))
43			debugger("Selection::Select() - "
44					 "unselected object in list!");
45		#endif
46
47		if (fSelected.AddItem((void*)object)) {
48			object->_SetSelected(true);
49			success = true;
50
51			Notify();
52		} else {
53			fprintf(stderr, "Selection::Select() - out of memory\n");
54		}
55	} else {
56
57		#if DEBUG
58		if (!fSelected.HasItem((void*)object))
59			debugger("Selection::Select() - "
60					 "already selected object not in list!");
61		#endif
62
63		success = true;
64		// object already in list
65	}
66
67	return success;
68}
69
70// Deselect
71void
72Selection::Deselect(Selectable* object)
73{
74	if (object->IsSelected()) {
75		if (!fSelected.RemoveItem((void*)object))
76			debugger("Selection::Deselect() - "
77					 "selected object not within list!");
78		object->_SetSelected(false);
79
80		Notify();
81	}
82}
83
84// DeselectAll
85void
86Selection::DeselectAll()
87{
88	_DeselectAllExcept(NULL);
89}
90
91// #pragma mark -
92
93// SelectableAt
94Selectable*
95Selection::SelectableAt(int32 index) const
96{
97	return (Selectable*)fSelected.ItemAt(index);
98}
99
100// SelectableAtFast
101Selectable*
102Selection::SelectableAtFast(int32 index) const
103{
104	return (Selectable*)fSelected.ItemAtFast(index);
105}
106
107// CountSelected
108int32
109Selection::CountSelected() const
110{
111	return fSelected.CountItems();
112}
113
114// #pragma mark -
115
116// _DeselectAllExcept
117void
118Selection::_DeselectAllExcept(Selectable* except)
119{
120	bool notify = false;
121	bool containedExcept = false;
122
123	int32 count = fSelected.CountItems();
124	for (int32 i = 0; i < count; i++) {
125		Selectable* object = (Selectable*)fSelected.ItemAtFast(i);
126		if (object != except) {
127			object->_SetSelected(false);
128			notify = true;
129		} else {
130			containedExcept = true;
131		}
132	}
133
134	fSelected.MakeEmpty();
135
136	// if the "except" object was previously
137	// in the selection, add it again after
138	// making the selection list empty
139	if (containedExcept)
140		fSelected.AddItem(except);
141
142	if (notify)
143		Notify();
144}
145
146