1/*
2Open Tracker License
3
4Terms and Conditions
5
6Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining a copy of
9this software and associated documentation files (the "Software"), to deal in
10the Software without restriction, including without limitation the rights to
11use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12of the Software, and to permit persons to whom the Software is furnished to do
13so, subject to the following conditions:
14
15The above copyright notice and this permission notice applies to all licensees
16and shall be included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25Except as contained in this notice, the name of Be Incorporated shall not be
26used in advertising or otherwise to promote the sale, use or other dealings in
27this Software without prior written authorization from Be Incorporated.
28
29Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30of Be Incorporated in the United States and other countries. Other brand product
31names are registered trademarks or trademarks of their respective holders.
32All rights reserved.
33*/
34
35
36#include <Message.h>
37#include <PropertyInfo.h>
38
39#include "ContainerWindow.h"
40#include "FSUtils.h"
41#include "Tracker.h"
42
43
44#define kPropertyTrash "Trash"
45#define kPropertyFolder "Folder"
46#define kPropertyPreferences "Preferences"
47
48
49/*
50Available scripting commands:
51
52doo Tracker delete Trash
53doo Tracker create Folder to '/boot/home/Desktop/hello'		# mkdir
54doo Tracker get Folder to '/boot/home/Desktop/hello'		# get window for path
55doo Tracker execute Folder to '/boot/home/Desktop/hello'	# open window
56
57ToDo:
58Create file: on a "Tracker" "File" "B_CREATE_PROPERTY" "name"
59Create query: on a "Tracker" "Query" "B_CREATE_PROPERTY" "name"
60*/
61
62
63const property_info kTrackerPropertyList[] = {
64	{
65		kPropertyTrash,
66		{ B_DELETE_PROPERTY },
67		{ B_DIRECT_SPECIFIER },
68		"delete Trash # Empties the Trash",
69		0,
70		{},
71		{},
72		{}
73	},
74	{
75		kPropertyFolder,
76		{ B_CREATE_PROPERTY, B_GET_PROPERTY, B_EXECUTE_PROPERTY },
77		{ B_DIRECT_SPECIFIER },
78		"create Folder to path # creates a new folder\n"
79		"get Folder to path # get Tracker window pointing to folder\n"
80		"execute Folder to path # opens Tracker window pointing to folder\n",
81		0,
82		{ B_REF_TYPE },
83		{},
84		{}
85	},
86	{
87		kPropertyPreferences,
88		{ B_EXECUTE_PROPERTY },
89		{ B_DIRECT_SPECIFIER },
90		"shows Tracker preferences",
91		0,
92		{},
93		{},
94		{}
95	},
96
97	{ 0 }
98};
99
100
101status_t
102TTracker::GetSupportedSuites(BMessage* data)
103{
104	data->AddString("suites", kTrackerSuites);
105	BPropertyInfo propertyInfo(const_cast<property_info*>(
106		kTrackerPropertyList));
107	data->AddFlat("messages", &propertyInfo);
108
109	return _inherited::GetSupportedSuites(data);
110}
111
112
113BHandler*
114TTracker::ResolveSpecifier(BMessage* message, int32 index, BMessage* specifier,
115	int32 form, const char* property)
116{
117	BPropertyInfo propertyInfo(const_cast<property_info*>(
118		kTrackerPropertyList));
119
120	int32 result = propertyInfo.FindMatch(message, index, specifier, form,
121		property);
122	if (result < 0) {
123		//PRINT(("FindMatch result %d %s\n", result, strerror(result)));
124		return _inherited::ResolveSpecifier(message, index, specifier,
125			form, property);
126	}
127
128	return this;
129}
130
131
132bool
133TTracker::HandleScriptingMessage(BMessage* message)
134{
135	if (message->what != B_GET_PROPERTY
136		&& message->what != B_SET_PROPERTY
137		&& message->what != B_CREATE_PROPERTY
138		&& message->what != B_COUNT_PROPERTIES
139		&& message->what != B_DELETE_PROPERTY
140		&& message->what != B_EXECUTE_PROPERTY) {
141		return false;
142	}
143
144	// dispatch scripting messages
145	BMessage reply(B_REPLY);
146	const char* property = NULL;
147	bool handled = false;
148
149	int32 index = 0;
150	int32 form = 0;
151	BMessage specifier;
152
153	status_t result = message->GetCurrentSpecifier(&index, &specifier,
154		&form, &property);
155	if (result != B_OK || index == -1)
156		return false;
157
158	ASSERT(property != NULL);
159
160	switch (message->what) {
161		case B_CREATE_PROPERTY:
162			handled = CreateProperty(message, &specifier, form, property,
163				&reply);
164			break;
165
166		case B_GET_PROPERTY:
167			handled = GetProperty(message, form, property, &reply);
168			break;
169
170		case B_SET_PROPERTY:
171			handled = SetProperty(message, &specifier, form, property,
172				&reply);
173			break;
174
175		case B_COUNT_PROPERTIES:
176			handled = CountProperty(&specifier, form, property, &reply);
177			break;
178
179		case B_DELETE_PROPERTY:
180			handled = DeleteProperty(&specifier, form, property, &reply);
181			break;
182
183		case B_EXECUTE_PROPERTY:
184			handled = ExecuteProperty(message, form, property, &reply);
185			break;
186	}
187
188	if (handled) {
189		// done handling message, send a reply
190		message->SendReply(&reply);
191	}
192
193	return handled;
194}
195
196
197bool
198TTracker::CreateProperty(BMessage* message, BMessage*, int32 form,
199	const char* property, BMessage* reply)
200{
201	bool handled = false;
202	status_t error = B_OK;
203
204	if (strcmp(property, kPropertyFolder) == 0) {
205		if (form != B_DIRECT_SPECIFIER)
206			return false;
207
208		// create new empty folders
209		entry_ref ref;
210		for (int32 index = 0;
211			message->FindRef("data", index, &ref) == B_OK; index++) {
212
213			BEntry entry(&ref);
214			if (!entry.Exists())
215				error = FSCreateNewFolder(&ref);
216
217			if (error != B_OK)
218				break;
219		}
220
221		handled = true;
222	}
223
224	if (error != B_OK)
225		reply->AddInt32("error", error);
226
227	return handled;
228}
229
230
231bool
232TTracker::DeleteProperty(BMessage*, int32 form, const char* property, BMessage*)
233{
234	if (strcmp(property, kPropertyTrash) == 0) {
235		// deleting on a selection is handled as removing a part of the
236		// selection not to be confused with deleting a selected item
237
238		if (form != B_DIRECT_SPECIFIER) {
239			// only support direct specifier
240			return false;
241		}
242
243		// empty the trash
244		FSEmptyTrash();
245
246		return true;
247
248	}
249
250	return false;
251}
252
253
254bool
255TTracker::ExecuteProperty(BMessage* message, int32 form, const char* property,
256	BMessage* reply)
257{
258	if (strcmp(property, kPropertyPreferences) == 0) {
259		if (form != B_DIRECT_SPECIFIER) {
260			// only support direct specifier
261			return false;
262		}
263		ShowSettingsWindow();
264
265		return true;
266	}
267
268	if (strcmp(property, kPropertyFolder) == 0) {
269		message->PrintToStream();
270		if (form != B_DIRECT_SPECIFIER)
271			return false;
272
273		// create new empty folders
274		entry_ref ref;
275		for (int32 index = 0;
276			message->FindRef("data", index, &ref) == B_OK; index++) {
277			status_t error = OpenRef(&ref, NULL, NULL, kOpen, NULL);
278
279			if (error == B_OK) {
280				reply->AddMessenger("window",
281					BMessenger(FindContainerWindow(&ref)));
282			} else {
283				reply->AddInt32("error", error);
284				break;
285			}
286		}
287
288		return true;
289	}
290
291	return false;
292}
293
294
295bool
296TTracker::CountProperty(BMessage*, int32, const char*, BMessage*)
297{
298	return false;
299}
300
301
302bool
303TTracker::GetProperty(BMessage* message, int32 form, const char* property,
304		BMessage* reply)
305{
306	if (strcmp(property, kPropertyFolder) == 0) {
307		message->PrintToStream();
308		if (form != B_DIRECT_SPECIFIER)
309			return false;
310
311		// create new empty folders
312		entry_ref ref;
313		for (int32 index = 0;
314			message->FindRef("data", index, &ref) == B_OK; index++) {
315			BHandler* window = FindContainerWindow(&ref);
316
317			if (window != NULL)
318				reply->AddMessenger("window", BMessenger(window));
319			else {
320				reply->AddInt32("error", B_NAME_NOT_FOUND);
321				break;
322			}
323		}
324
325		return true;
326	}
327
328	return false;
329}
330
331
332bool
333TTracker::SetProperty(BMessage*, BMessage*, int32, const char*, BMessage*)
334{
335	return false;
336}
337