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