102be5353SAxel Dörfler/*
202be5353SAxel DörflerOpen Tracker License
302be5353SAxel Dörfler
402be5353SAxel DörflerTerms and Conditions
502be5353SAxel Dörfler
602be5353SAxel DörflerCopyright (c) 1991-2000, Be Incorporated. All rights reserved.
702be5353SAxel Dörfler
802be5353SAxel DörflerPermission is hereby granted, free of charge, to any person obtaining a copy of
902be5353SAxel Dörflerthis software and associated documentation files (the "Software"), to deal in
1002be5353SAxel Dörflerthe Software without restriction, including without limitation the rights to
1102be5353SAxel Dörfleruse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1202be5353SAxel Dörflerof the Software, and to permit persons to whom the Software is furnished to do
1302be5353SAxel Dörflerso, subject to the following conditions:
1402be5353SAxel Dörfler
1502be5353SAxel DörflerThe above copyright notice and this permission notice applies to all licensees
1602be5353SAxel Dörflerand shall be included in all copies or substantial portions of the Software.
1702be5353SAxel Dörfler
2402be5353SAxel Dörfler
2502be5353SAxel DörflerExcept as contained in this notice, the name of Be Incorporated shall not be
2602be5353SAxel Dörflerused in advertising or otherwise to promote the sale, use or other dealings in
2702be5353SAxel Dörflerthis Software without prior written authorization from Be Incorporated.
2802be5353SAxel Dörfler
2902be5353SAxel DörflerTracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
3002be5353SAxel Dörflerof Be Incorporated in the United States and other countries. Other brand product
3102be5353SAxel Dörflernames are registered trademarks or trademarks of their respective holders.
3202be5353SAxel DörflerAll rights reserved.
3302be5353SAxel Dörfler*/
3402be5353SAxel Dörfler
3502be5353SAxel Dörfler//	PoseView scripting interface
3602be5353SAxel Dörfler
3702be5353SAxel Dörfler#include <stdlib.h>
3802be5353SAxel Dörfler#include <stdio.h>
3902be5353SAxel Dörfler#include <string.h>
4002be5353SAxel Dörfler
4109b83e5cSAxel Dörfler#include <ByteOrder.h>
4202be5353SAxel Dörfler#include <Debug.h>
4302be5353SAxel Dörfler#include <Message.h>
4402be5353SAxel Dörfler#include <PropertyInfo.h>
4502be5353SAxel Dörfler
4602be5353SAxel Dörfler#include "Tracker.h"
4702be5353SAxel Dörfler#include "PoseView.h"
4802be5353SAxel Dörfler
4902be5353SAxel Dörfler#define kPosesSuites "suite/vnd.Be-TrackerPoses"
5002be5353SAxel Dörfler
5102be5353SAxel Dörfler#define kPropertyPath "Path"
5202be5353SAxel Dörfler
5302be5353SAxel Dörfler// notes on PoseView scripting interface:
5402be5353SAxel Dörfler// Indices and entry_refs are used to specify poses; In the case of indices
5502be5353SAxel Dörfler// and previous/next specifiers the current PoseView sort order is used.
5602be5353SAxel Dörfler// If PoseView is not in list view mode, the order in which poses are indexed
5702be5353SAxel Dörfler// is arbitrary.
58ea001e58SJohn Scipione// Both of these specifiers, but indices more so, are likely to be accurate
59ea001e58SJohn Scipione// only untill a next change to the PoseView (a change may be adding,
60ea001e58SJohn Scipione// removing a pose, changing an attribute or stat resulting in a sort ordering
61ea001e58SJohn Scipione// change, changing the sort ordering rule. When getting a selected item,
62ea001e58SJohn Scipione// there is no guarantee that the item will still be selected after the
63ea001e58SJohn Scipione// operation. The client must be able to deal with these inaccuracies.
6402be5353SAxel Dörfler// Specifying an index/entry_ref that no longer exists will be handled well.
6502be5353SAxel Dörfler
6602be5353SAxel Dörfler#if 0
6702be5353SAxel Dörflerdoo Tracker get Suites of Poses of Window test
6802be5353SAxel Dörflerdoo Tracker get Path of Poses of Window test
6902be5353SAxel Dörflerdoo Tracker count Entry of Poses of Window test
7002be5353SAxel Dörflerdoo Tracker get Entry of Poses of Window test
7102be5353SAxel Dörflerdoo Tracker get Entry 2 of Poses of Window test
7202be5353SAxel Dörflerdoo Tracker count Selection of Poses of Window test
7302be5353SAxel Dörflerdoo Tracker get Selection of Poses of Window test
7402be5353SAxel Dörflerdoo Tracker delete Entry 'test/6L6' of Poses of Window test
7502be5353SAxel Dörflerdoo Tracker execute Entry 'test/6L6' of Poses of Window test
7602be5353SAxel Dörflerdoo Tracker execute Entry 2 of Poses of Window test
7702be5353SAxel Dörflerdoo Tracker set Selection of Poses of Window test to [0,2]
7802be5353SAxel Dörflerdoo Tracker set Selection of Poses of Window test to 'test/KT55'
7902be5353SAxel Dörflerdoo Tracker create Selection of Poses of Window test to 'test/EL34'
8002be5353SAxel Dörflerdoo Tracker delete Selection 'test/EL34' of Poses of Window test
8102be5353SAxel Dörfler#endif
8202be5353SAxel Dörfler
8302be5353SAxel Dörfler// ToDo:
8402be5353SAxel Dörfler//	access list view column state
8502be5353SAxel Dörfler//	access poses
8602be5353SAxel Dörfler//				- pose location
8702be5353SAxel Dörfler//				- pose text widgets
8802be5353SAxel Dörfler
8902be5353SAxel Dörfler
9002be5353SAxel Dörflerconst property_info kPosesPropertyList[] = {
9102be5353SAxel Dörfler	{	kPropertyPath,
9202be5353SAxel Dörfler		{ B_GET_PROPERTY },
9302be5353SAxel Dörfler		{ B_DIRECT_SPECIFIER },
9402be5353SAxel Dörfler		"get Path of ... # returns the path of a Tracker window, "
9502be5353SAxel Dörfler			"error if no path associated",
9602be5353SAxel Dörfler		0,
9702be5353SAxel Dörfler		{ B_REF_TYPE },
9802be5353SAxel Dörfler		{},
9902be5353SAxel Dörfler		{}
10002be5353SAxel Dörfler	},
10102be5353SAxel Dörfler	{	kPropertyEntry,
10202be5353SAxel Dörfler		{ B_COUNT_PROPERTIES },
10302be5353SAxel Dörfler		{ B_DIRECT_SPECIFIER },
10402be5353SAxel Dörfler		"count Entry of ... # count entries in a PoseView",
10502be5353SAxel Dörfler		0,
10602be5353SAxel Dörfler		{ B_INT32_TYPE },
10702be5353SAxel Dörfler		{},
10802be5353SAxel Dörfler		{}
10902be5353SAxel Dörfler	},
11002be5353SAxel Dörfler	{	kPropertyEntry,
11102be5353SAxel Dörfler		{ B_DELETE_PROPERTY },
11202be5353SAxel Dörfler		{ B_ENTRY_SPECIFIER, B_INDEX_SPECIFIER },
11302be5353SAxel Dörfler		"delete Entry {path|index} # deletes specified entries in a PoseView",
11402be5353SAxel Dörfler		0,
11502be5353SAxel Dörfler		{},
11602be5353SAxel Dörfler		{},
11702be5353SAxel Dörfler		{}
11802be5353SAxel Dörfler	},
11902be5353SAxel Dörfler	{	kPropertyEntry,
12002be5353SAxel Dörfler		{ B_GET_PROPERTY },
121ea001e58SJohn Scipione		{ B_DIRECT_SPECIFIER, B_INDEX_SPECIFIER, kPreviousSpecifier,
122ea001e58SJohn Scipione			kNextSpecifier },
12302be5353SAxel Dörfler		"get Entry [next|previous|index] # returns specified entries",
12402be5353SAxel Dörfler		0,
12502be5353SAxel Dörfler		{ B_REF_TYPE },
12602be5353SAxel Dörfler		{},
12702be5353SAxel Dörfler		{}
12802be5353SAxel Dörfler	},
12902be5353SAxel Dörfler	{	kPropertyEntry,
13002be5353SAxel Dörfler		{ B_EXECUTE_PROPERTY },
13102be5353SAxel Dörfler		{ B_ENTRY_SPECIFIER, B_INDEX_SPECIFIER },
13202be5353SAxel Dörfler		"execute Entry {path|index}	# opens specified entries",
13302be5353SAxel Dörfler		0,
13402be5353SAxel Dörfler		{ B_REF_TYPE },
13502be5353SAxel Dörfler		{},
13602be5353SAxel Dörfler		{}
13702be5353SAxel Dörfler	},
13802be5353SAxel Dörfler	{	kPropertySelection,
13902be5353SAxel Dörfler		{ B_GET_PROPERTY },
14002be5353SAxel Dörfler		{ B_DIRECT_SPECIFIER, kPreviousSpecifier, kNextSpecifier },
14102be5353SAxel Dörfler		"get Selection [next|previous] # returns the selected entries",
14202be5353SAxel Dörfler		0,
14302be5353SAxel Dörfler		{ B_REF_TYPE },
14402be5353SAxel Dörfler		{},
14502be5353SAxel Dörfler		{}
14602be5353SAxel Dörfler	},
14702be5353SAxel Dörfler	{	kPropertySelection,
14802be5353SAxel Dörfler		{ B_SET_PROPERTY },
14902be5353SAxel Dörfler		{ B_DIRECT_SPECIFIER, kPreviousSpecifier, kNextSpecifier },
150ea001e58SJohn Scipione		"set Selection of ... to {next|previous|entry} # selects specified "
151ea001e58SJohn Scipione		"entries",
15202be5353SAxel Dörfler		0,
15302be5353SAxel Dörfler		{},
15402be5353SAxel Dörfler		{},
15502be5353SAxel Dörfler		{}
15602be5353SAxel Dörfler	},
15702be5353SAxel Dörfler	{	kPropertySelection,
15802be5353SAxel Dörfler		{ B_COUNT_PROPERTIES },
15902be5353SAxel Dörfler		{ B_DIRECT_SPECIFIER },
16002be5353SAxel Dörfler		"count Selection of ... # counts selected items",
16102be5353SAxel Dörfler		0,
16202be5353SAxel Dörfler		{ B_INT32_TYPE },
16302be5353SAxel Dörfler		{},
16402be5353SAxel Dörfler		{}
16502be5353SAxel Dörfler	},
16602be5353SAxel Dörfler	{	kPropertySelection,
16702be5353SAxel Dörfler		{ B_CREATE_PROPERTY },
16802be5353SAxel Dörfler		{ B_DIRECT_SPECIFIER },
16902be5353SAxel Dörfler		"create selection of ... to {entry|index} "
17002be5353SAxel Dörfler		"# adds specified items to a selection in a PoseView",
17102be5353SAxel Dörfler		0,
17202be5353SAxel Dörfler		{},
17302be5353SAxel Dörfler		{},
17402be5353SAxel Dörfler		{}
17502be5353SAxel Dörfler	},
17602be5353SAxel Dörfler	{	kPropertySelection,
17702be5353SAxel Dörfler		{ B_DELETE_PROPERTY },
17802be5353SAxel Dörfler		{ B_ENTRY_SPECIFIER, B_INDEX_SPECIFIER },
17902be5353SAxel Dörfler		"delete selection {path|index} of ... "
18002be5353SAxel Dörfler		"# removes specified items from a selection in a PoseView",
18102be5353SAxel Dörfler		0,
18202be5353SAxel Dörfler		{},
18302be5353SAxel Dörfler		{},
18402be5353SAxel Dörfler		{}
18502be5353SAxel Dörfler	},
18716af9b4cSHumdinger	{ 0 }
18802be5353SAxel Dörfler};
18902be5353SAxel Dörfler
190b05aa8b5SJohn Scipione
19102be5353SAxel Dörflerstatus_t
19292dd9f73SAdrien DestuguesBPoseView::GetSupportedSuites(BMessage* data)
19302be5353SAxel Dörfler{
19402be5353SAxel Dörfler	data->AddString("suites", kPosesSuites);
195ea001e58SJohn Scipione	BPropertyInfo propertyInfo(
196ea001e58SJohn Scipione		const_cast<property_info*>(kPosesPropertyList));
19702be5353SAxel Dörfler	data->AddFlat("messages", &propertyInfo);
198db416834SMatt Madia
19902be5353SAxel Dörfler	return _inherited::GetSupportedSuites(data);
20002be5353SAxel Dörfler}
20102be5353SAxel Dörfler
202b05aa8b5SJohn Scipione
20302be5353SAxel Dörflerbool
20492dd9f73SAdrien DestuguesBPoseView::HandleScriptingMessage(BMessage* message)
20502be5353SAxel Dörfler{
20602be5353SAxel Dörfler	if (message->what != B_GET_PROPERTY
20702be5353SAxel Dörfler		&& message->what != B_SET_PROPERTY
20802be5353SAxel Dörfler		&& message->what != B_CREATE_PROPERTY
20902be5353SAxel Dörfler		&& message->what != B_COUNT_PROPERTIES
21002be5353SAxel Dörfler		&& message->what != B_DELETE_PROPERTY
211850b01ceSJohn Scipione		&& message->what != B_EXECUTE_PROPERTY) {
21202be5353SAxel Dörfler		return false;
213850b01ceSJohn Scipione	}
21402be5353SAxel Dörfler
21502be5353SAxel Dörfler	// dispatch scripting messages
21602be5353SAxel Dörfler	BMessage reply(B_REPLY);
217b05aa8b5SJohn Scipione	const char* property = 0;
21802be5353SAxel Dörfler	bool handled = false;
21902be5353SAxel Dörfler
22002be5353SAxel Dörfler	int32 index = 0;
22102be5353SAxel Dörfler	int32 form = 0;
22202be5353SAxel Dörfler	BMessage specifier;
22302be5353SAxel Dörfler	status_t result = message->GetCurrentSpecifier(&index, &specifier,
22402be5353SAxel Dörfler		&form, &property);
22502be5353SAxel Dörfler
226b05aa8b5SJohn Scipione	if (result != B_OK || index == -1)
22702be5353SAxel Dörfler		return false;
228db416834SMatt Madia
229850b01ceSJohn Scipione	ASSERT(property != NULL);
230db416834SMatt Madia
23102be5353SAxel Dörfler	switch (message->what) {
23202be5353SAxel Dörfler		case B_CREATE_PROPERTY:
233ea001e58SJohn Scipione			handled = CreateProperty(message, &specifier, form, property,
234ea001e58SJohn Scipione				&reply);
23502be5353SAxel Dörfler			break;
23602be5353SAxel Dörfler
23702be5353SAxel Dörfler		case B_GET_PROPERTY:
23802be5353SAxel Dörfler			handled = GetProperty(&specifier, form, property, &reply);
23902be5353SAxel Dörfler			break;
240db416834SMatt Madia
24102be5353SAxel Dörfler		case B_SET_PROPERTY:
242ea001e58SJohn Scipione			handled = SetProperty(message, &specifier, form, property,
243ea001e58SJohn Scipione				&reply);
24402be5353SAxel Dörfler			break;
245db416834SMatt Madia
24602be5353SAxel Dörfler		case B_COUNT_PROPERTIES:
24702be5353SAxel Dörfler			handled = CountProperty(&specifier, form, property, &reply);
24802be5353SAxel Dörfler			break;
24902be5353SAxel Dörfler
25002be5353SAxel Dörfler		case B_DELETE_PROPERTY:
25102be5353SAxel Dörfler			handled = DeleteProperty(&specifier, form, property, &reply);
25202be5353SAxel Dörfler			break;
253db416834SMatt Madia
25402be5353SAxel Dörfler		case B_EXECUTE_PROPERTY:
25502be5353SAxel Dörfler			handled = ExecuteProperty(&specifier, form, property, &reply);
25602be5353SAxel Dörfler			break;
25702be5353SAxel Dörfler	}
25802be5353SAxel Dörfler
259b05aa8b5SJohn Scipione	if (handled) {
26002be5353SAxel Dörfler		// done handling message, send a reply
26102be5353SAxel Dörfler		message->SendReply(&reply);
262b05aa8b5SJohn Scipione	}
263b05aa8b5SJohn Scipione
26402be5353SAxel Dörfler	return handled;
26502be5353SAxel Dörfler}
26602be5353SAxel Dörfler
267b05aa8b5SJohn Scipione
26802be5353SAxel Dörflerbool
26992dd9f73SAdrien DestuguesBPoseView::ExecuteProperty(BMessage* specifier, int32 form,
27092dd9f73SAdrien Destugues	const char* property, BMessage* reply)
27102be5353SAxel Dörfler{
272850b01ceSJohn Scipione	status_t result = B_OK;
27302be5353SAxel Dörfler	bool handled = false;
27402be5353SAxel Dörfler	if (strcmp(property, kPropertyEntry) == 0) {
27502be5353SAxel Dörfler		BMessage launchMessage(B_REFS_RECEIVED);
276db416834SMatt Madia
27702be5353SAxel Dörfler		if (form == (int32)B_ENTRY_SPECIFIER) {
27802be5353SAxel Dörfler			// move all poses specified by entry_ref to Trash
27902be5353SAxel Dörfler			entry_ref ref;
28002be5353SAxel Dörfler			for (int32 index = 0; specifier->FindRef("refs", index, &ref)
28102be5353SAxel Dörfler				== B_OK; index++)
28202be5353SAxel Dörfler				launchMessage.AddRef("refs", &ref);
28302be5353SAxel Dörfler		} else if (form == (int32)B_INDEX_SPECIFIER) {
28402be5353SAxel Dörfler			// move all poses specified by index to Trash
28502be5353SAxel Dörfler			int32 specifyingIndex;
28602be5353SAxel Dörfler			for (int32 index = 0; specifier->FindInt32("index", index,
28702be5353SAxel Dörfler				&specifyingIndex) == B_OK; index++) {
288b05aa8b5SJohn Scipione				BPose* pose = PoseAtIndex(specifyingIndex);
28902be5353SAxel Dörfler
290850b01ceSJohn Scipione				if (pose == NULL) {
291850b01ceSJohn Scipione					result = B_ENTRY_NOT_FOUND;
29202be5353SAxel Dörfler					break;
29302be5353SAxel Dörfler				}
29402be5353SAxel Dörfler
29502be5353SAxel Dörfler				launchMessage.AddRef("refs", pose->TargetModel()->EntryRef());
29602be5353SAxel Dörfler			}
29702be5353SAxel Dörfler		} else
29802be5353SAxel Dörfler			return false;
29902be5353SAxel Dörfler
300850b01ceSJohn Scipione		if (result == B_OK) {
30102be5353SAxel Dörfler			// add a messenger to the launch message that will be used to
30202be5353SAxel Dörfler			// dispatch scripting calls from apps to the PoseView
303ea001e58SJohn Scipione			launchMessage.AddMessenger("TrackerViewToken",
304ea001e58SJohn Scipione				BMessenger(this, 0, 0));
30502be5353SAxel Dörfler			if (fSelectionHandler)
30602be5353SAxel Dörfler				fSelectionHandler->PostMessage(&launchMessage);
30702be5353SAxel Dörfler		}
30802be5353SAxel Dörfler		handled = true;
30902be5353SAxel Dörfler	}
31002be5353SAxel Dörfler
311850b01ceSJohn Scipione	if (result != B_OK)
312850b01ceSJohn Scipione		reply->AddInt32("error", result);
31302be5353SAxel Dörfler
31402be5353SAxel Dörfler	return handled;
31502be5353SAxel Dörfler}
31602be5353SAxel Dörfler
317b05aa8b5SJohn Scipione
31802be5353SAxel Dörflerbool
31992dd9f73SAdrien DestuguesBPoseView::CreateProperty(BMessage* specifier, BMessage*, int32 form,
32092dd9f73SAdrien Destugues	const char* property, BMessage* reply)
32102be5353SAxel Dörfler{
322850b01ceSJohn Scipione	status_t result = B_OK;
32302be5353SAxel Dörfler	bool handled = false;
32402be5353SAxel Dörfler	if (strcmp(property, kPropertySelection) == 0) {
32502be5353SAxel Dörfler		// creating on a selection expands the current selection
32602be5353SAxel Dörfler
32702be5353SAxel Dörfler		if (form != B_DIRECT_SPECIFIER)
32802be5353SAxel Dörfler			// only support direct specifier
32902be5353SAxel Dörfler			return false;
33002be5353SAxel Dörfler
33102be5353SAxel Dörfler		// items to add to a selection may be passed as refs or as indices
33202be5353SAxel Dörfler		if (specifier->HasRef("data")) {
33302be5353SAxel Dörfler			entry_ref ref;
33402be5353SAxel Dörfler			// select poses specified by entries
33502be5353SAxel Dörfler			for (int32 index = 0; specifier->FindRef("data", index, &ref)
336850b01ceSJohn Scipione					== B_OK; index++) {
33702be5353SAxel Dörfler				int32 poseIndex;
338b05aa8b5SJohn Scipione				BPose* pose = FindPose(&ref, form, &poseIndex);
33902be5353SAxel Dörfler
340850b01ceSJohn Scipione				if (pose == NULL) {
341850b01ceSJohn Scipione					result = B_ENTRY_NOT_FOUND;
34202be5353SAxel Dörfler					handled = true;
34302be5353SAxel Dörfler					break;
34402be5353SAxel Dörfler				}
34502be5353SAxel Dörfler
34602be5353SAxel Dörfler				AddPoseToSelection(pose, poseIndex);
34702be5353SAxel Dörfler			}
34802be5353SAxel Dörfler			handled = true;
34902be5353SAxel Dörfler		} else {
35002be5353SAxel Dörfler			// select poses specified by indices
35102be5353SAxel Dörfler			int32 specifyingIndex;
35202be5353SAxel Dörfler			for (int32 index = 0; specifier->FindInt32("data", index,
353850b01ceSJohn Scipione					&specifyingIndex) == B_OK; index++) {
354b05aa8b5SJohn Scipione				BPose* pose = PoseAtIndex(specifyingIndex);
355850b01ceSJohn Scipione				if (pose == NULL) {
356850b01ceSJohn Scipione					result = B_BAD_INDEX;
35702be5353SAxel Dörfler					handled = true;
35802be5353SAxel Dörfler					break;
35902be5353SAxel Dörfler				}
36002be5353SAxel Dörfler
36102be5353SAxel Dörfler				AddPoseToSelection(pose, specifyingIndex);
36202be5353SAxel Dörfler			}
36302be5353SAxel Dörfler			handled = true;
36402be5353SAxel Dörfler		}
36502be5353SAxel Dörfler	}
36602be5353SAxel Dörfler
367850b01ceSJohn Scipione	if (result != B_OK)
368850b01ceSJohn Scipione		reply->AddInt32("error", result);
36902be5353SAxel Dörfler
37002be5353SAxel Dörfler	return handled;
37102be5353SAxel Dörfler}
37202be5353SAxel Dörfler
373b05aa8b5SJohn Scipione
37402be5353SAxel Dörflerbool
37592dd9f73SAdrien DestuguesBPoseView::DeleteProperty(BMessage* specifier, int32 form,
37692dd9f73SAdrien Destugues	const char* property, BMessage* reply)
37702be5353SAxel Dörfler{
378850b01ceSJohn Scipione	status_t result = B_OK;
37902be5353SAxel Dörfler	bool handled = false;
38002be5353SAxel Dörfler
38102be5353SAxel Dörfler	if (strcmp(property, kPropertySelection) == 0) {
382ea001e58SJohn Scipione		// deleting on a selection is handled as removing a part of the
383ea001e58SJohn Scipione		// selection not to be confused with deleting a selected item
38402be5353SAxel Dörfler
38502be5353SAxel Dörfler		if (form == (int32)B_ENTRY_SPECIFIER) {
38602be5353SAxel Dörfler			entry_ref ref;
38702be5353SAxel Dörfler			// select poses specified by entries
38802be5353SAxel Dörfler			for (int32 index = 0; specifier->FindRef("refs", index, &ref)
389850b01ceSJohn Scipione					== B_OK; index++) {
39002be5353SAxel Dörfler				int32 poseIndex;
391b05aa8b5SJohn Scipione				BPose* pose = FindPose(&ref, form, &poseIndex);
39202be5353SAxel Dörfler
393850b01ceSJohn Scipione				if (pose == NULL) {
394850b01ceSJohn Scipione					result = B_ENTRY_NOT_FOUND;
39502be5353SAxel Dörfler					break;
39602be5353SAxel Dörfler				}
39702be5353SAxel Dörfler
39802be5353SAxel Dörfler				RemovePoseFromSelection(pose);
39902be5353SAxel Dörfler			}
40002be5353SAxel Dörfler			handled = true;
40102be5353SAxel Dörfler
40202be5353SAxel Dörfler		} else if (form == B_INDEX_SPECIFIER) {
40302be5353SAxel Dörfler			// move all poses specified by index to Trash
40402be5353SAxel Dörfler			int32 specifyingIndex;
40502be5353SAxel Dörfler			for (int32 index = 0; specifier->FindInt32("index", index,
406850b01ceSJohn Scipione					&specifyingIndex) == B_OK; index++) {
407b05aa8b5SJohn Scipione				BPose* pose = PoseAtIndex(specifyingIndex);
40802be5353SAxel Dörfler
409850b01ceSJohn Scipione				if (pose == NULL) {
410850b01ceSJohn Scipione					result = B_BAD_INDEX;
41102be5353SAxel Dörfler					break;
41202be5353SAxel Dörfler				}
41302be5353SAxel Dörfler
41402be5353SAxel Dörfler				RemovePoseFromSelection(pose);
41502be5353SAxel Dörfler			}
41602be5353SAxel Dörfler			handled = true;
41702be5353SAxel Dörfler		} else
41802be5353SAxel Dörfler			return false;
41902be5353SAxel Dörfler
42002be5353SAxel Dörfler	} else if (strcmp(property, kPropertyEntry) == 0) {
42102be5353SAxel Dörfler		// deleting entries is handled by moving entries to trash
422ea001e58SJohn Scipione
42302be5353SAxel Dörfler		// build a list of entries, specified by the specifier
424b05aa8b5SJohn Scipione		BObjectList<entry_ref>* entryList = new BObjectList<entry_ref>();
425b05aa8b5SJohn Scipione			// list will be deleted for us by the trashing thread
42602be5353SAxel Dörfler
42702be5353SAxel Dörfler		if (form == (int32)B_ENTRY_SPECIFIER) {
42802be5353SAxel Dörfler			// move all poses specified by entry_ref to Trash
42902be5353SAxel Dörfler			entry_ref ref;
43002be5353SAxel Dörfler			for (int32 index = 0; specifier->FindRef("refs", index, &ref)
431850b01ceSJohn Scipione					== B_OK; index++) {
43202be5353SAxel Dörfler				entryList->AddItem(new entry_ref(ref));
433850b01ceSJohn Scipione			}
43402be5353SAxel Dörfler		} else if (form == (int32)B_INDEX_SPECIFIER) {
43502be5353SAxel Dörfler			// move all poses specified by index to Trash
43602be5353SAxel Dörfler			int32 specifyingIndex;
437ea001e58SJohn Scipione			for (int32 index = 0; specifier->FindInt32("index", index,
438ea001e58SJohn Scipione					&specifyingIndex) == B_OK; index++) {
439b05aa8b5SJohn Scipione				BPose* pose = PoseAtIndex(specifyingIndex);
44002be5353SAxel Dörfler
441850b01ceSJohn Scipione				if (pose == NULL) {
442850b01ceSJohn Scipione					result = B_BAD_INDEX;
44302be5353SAxel Dörfler					break;
44402be5353SAxel Dörfler				}
44502be5353SAxel Dörfler
446ea001e58SJohn Scipione				entryList->AddItem(
447ea001e58SJohn Scipione					new entry_ref(*pose->TargetModel()->EntryRef()));
44802be5353SAxel Dörfler			}
44915f61ef9SAdrien Destugues		} else {
45015f61ef9SAdrien Destugues			delete entryList;
45102be5353SAxel Dörfler			return false;
45215f61ef9SAdrien Destugues		}
45302be5353SAxel Dörfler
454850b01ceSJohn Scipione		if (result == B_OK) {
45502be5353SAxel Dörfler			TrackerSettings settings;
456163a3948SHumdinger			if (!settings.DontMoveFilesToTrash()) {
457ea001e58SJohn Scipione				// move the list we build into trash, don't make the
458ea001e58SJohn Scipione				// trashing task select the next item
45902be5353SAxel Dörfler				MoveListToTrash(entryList, false, false);
46002be5353SAxel Dörfler			} else
46102be5353SAxel Dörfler				Delete(entryList, false, settings.AskBeforeDeleteFile());
46215f61ef9SAdrien Destugues		} else {
46351a0d540SAdrien Destugues			for (int i = entryList->CountItems() - 1; i >= 0; i--)
464267d1d78SAdrien Destugues				delete entryList->ItemAt(i);
46515f61ef9SAdrien Destugues			delete entryList;
46602be5353SAxel Dörfler		}
46702be5353SAxel Dörfler
46802be5353SAxel Dörfler		handled = true;
46902be5353SAxel Dörfler	}
47002be5353SAxel Dörfler
471850b01ceSJohn Scipione	if (result != B_OK)
472850b01ceSJohn Scipione		reply->AddInt32("error", result);
47302be5353SAxel Dörfler
47402be5353SAxel Dörfler	return handled;
47502be5353SAxel Dörfler}
47602be5353SAxel Dörfler
477b05aa8b5SJohn Scipione
47802be5353SAxel Dörflerbool
47992dd9f73SAdrien DestuguesBPoseView::CountProperty(BMessage*, int32, const char* property,
48092dd9f73SAdrien Destugues	BMessage* reply)
48102be5353SAxel Dörfler{
48202be5353SAxel Dörfler	bool handled = false;
483ea001e58SJohn Scipione	//PRINT(("BPoseView::CountProperty, %s\n", property));
48402be5353SAxel Dörfler
48502be5353SAxel Dörfler	// just return the respecitve counts
48602be5353SAxel Dörfler	if (strcmp(property, kPropertySelection) == 0) {
48702be5353SAxel Dörfler		reply->AddInt32("result", fSelectionList->CountItems());
48802be5353SAxel Dörfler		handled = true;
48902be5353SAxel Dörfler	} else if (strcmp(property, kPropertyEntry) == 0) {
49002be5353SAxel Dörfler		reply->AddInt32("result", fPoseList->CountItems());
49102be5353SAxel Dörfler		handled = true;
49202be5353SAxel Dörfler	}
493850b01ceSJohn Scipione
49402be5353SAxel Dörfler	return handled;
49502be5353SAxel Dörfler}
49602be5353SAxel Dörfler
497b05aa8b5SJohn Scipione
49802be5353SAxel Dörflerbool
49992dd9f73SAdrien DestuguesBPoseView::GetProperty(BMessage* specifier, int32 form,
50092dd9f73SAdrien Destugues	const char* property, BMessage* reply)
50102be5353SAxel Dörfler{
50202be5353SAxel Dörfler//	PRINT(("GetProperty %s\n", property));
50302be5353SAxel Dörfler	bool handled = false;
504850b01ceSJohn Scipione	status_t result = B_OK;
50502be5353SAxel Dörfler
50602be5353SAxel Dörfler	if (strcmp(property, kPropertyPath) == 0) {
50702be5353SAxel Dörfler		if (form == B_DIRECT_SPECIFIER) {
50802be5353SAxel Dörfler			handled = true;
509850b01ceSJohn Scipione			if (TargetModel() == NULL)
510850b01ceSJohn Scipione				result = B_NOT_A_DIRECTORY;
511b05aa8b5SJohn Scipione			else
51202be5353SAxel Dörfler				reply->AddRef("result", TargetModel()->EntryRef());
51302be5353SAxel Dörfler		}
51402be5353SAxel Dörfler	} else if (strcmp(property, kPropertySelection) == 0) {
51502be5353SAxel Dörfler		int32 count = fSelectionList->CountItems();
51602be5353SAxel Dörfler		switch (form) {
51702be5353SAxel Dörfler			case B_DIRECT_SPECIFIER:
51802be5353SAxel Dörfler				// return entries of all poses in selection
519850b01ceSJohn Scipione				for (int32 index = 0; index < count; index++) {
52002be5353SAxel Dörfler					reply->AddRef("result", fSelectionList->ItemAt(index)->
52102be5353SAxel Dörfler						TargetModel()->EntryRef());
522850b01ceSJohn Scipione				}
52302be5353SAxel Dörfler
52402be5353SAxel Dörfler				handled = true;
52502be5353SAxel Dörfler				break;
52602be5353SAxel Dörfler
52702be5353SAxel Dörfler			case kPreviousSpecifier:
52802be5353SAxel Dörfler			case kNextSpecifier:
52902be5353SAxel Dörfler				{
53002be5353SAxel Dörfler					// return entry and index of selected pose before or after
53102be5353SAxel Dörfler					// specified pose
53202be5353SAxel Dörfler					entry_ref ref;
53302be5353SAxel Dörfler					if (specifier->FindRef("data", &ref) != B_OK)
53402be5353SAxel Dörfler						break;
535db416834SMatt Madia
53602be5353SAxel Dörfler					int32 poseIndex;
537b05aa8b5SJohn Scipione					BPose* pose = FindPose(&ref, &poseIndex);
538db416834SMatt Madia
53902be5353SAxel Dörfler					for (;;) {
54002be5353SAxel Dörfler						if (form == (int32)kPreviousSpecifier)
54102be5353SAxel Dörfler							pose = PoseAtIndex(--poseIndex);
54202be5353SAxel Dörfler						else if (form == (int32)kNextSpecifier)
54302be5353SAxel Dörfler							pose = PoseAtIndex(++poseIndex);
544db416834SMatt Madia
545850b01ceSJohn Scipione						if (pose == NULL) {
546850b01ceSJohn Scipione							result = B_ENTRY_NOT_FOUND;
54702be5353SAxel Dörfler							break;
54802be5353SAxel Dörfler						}
549db416834SMatt Madia
55002be5353SAxel Dörfler						if (pose->IsSelected()) {
551ea001e58SJohn Scipione							reply->AddRef("result",
552ea001e58SJohn Scipione								pose->TargetModel()->EntryRef());
55302be5353SAxel Dörfler							reply->AddInt32("index", IndexOfPose(pose));
55402be5353SAxel Dörfler							break;
55502be5353SAxel Dörfler						}
55602be5353SAxel Dörfler					}
557db416834SMatt Madia
55802be5353SAxel Dörfler					handled = true;
55902be5353SAxel Dörfler					break;
56002be5353SAxel Dörfler				}
56102be5353SAxel Dörfler		}
56202be5353SAxel Dörfler	} else if (strcmp(property, kPropertyEntry) == 0) {
56302be5353SAxel Dörfler		int32 count = fPoseList->CountItems();
56402be5353SAxel Dörfler		switch (form) {
56502be5353SAxel Dörfler			case B_DIRECT_SPECIFIER:
566b05aa8b5SJohn Scipione			{
56702be5353SAxel Dörfler				// return all entries of all poses in PoseView
568ea001e58SJohn Scipione				for (int32 index = 0; index < count; index++) {
569ea001e58SJohn Scipione					reply->AddRef("result",
570ea001e58SJohn Scipione						PoseAtIndex(index)->TargetModel()->EntryRef());
571ea001e58SJohn Scipione				}
57202be5353SAxel Dörfler
57302be5353SAxel Dörfler				handled = true;
57402be5353SAxel Dörfler				break;
575b05aa8b5SJohn Scipione			}
576b05aa8b5SJohn Scipione
57702be5353SAxel Dörfler			case B_INDEX_SPECIFIER:
578b05aa8b5SJohn Scipione			{
579b05aa8b5SJohn Scipione				// return entry at index
580b05aa8b5SJohn Scipione				int32 index;
581b05aa8b5SJohn Scipione				if (specifier->FindInt32("index", &index) != B_OK)
582b05aa8b5SJohn Scipione					break;
583db416834SMatt Madia
584b05aa8b5SJohn Scipione				if (!PoseAtIndex(index)) {
585850b01ceSJohn Scipione					result = B_BAD_INDEX;
58602be5353SAxel Dörfler					handled = true;
58702be5353SAxel Dörfler					break;
58802be5353SAxel Dörfler				}
589ea001e58SJohn Scipione				reply->AddRef("result",
590ea001e58SJohn Scipione					PoseAtIndex(index)->TargetModel()->EntryRef());
591b05aa8b5SJohn Scipione
592b05aa8b5SJohn Scipione				handled = true;
593b05aa8b5SJohn Scipione				break;
594b05aa8b5SJohn Scipione			}
595b05aa8b5SJohn Scipione
59602be5353SAxel Dörfler			case kPreviousSpecifier:
59702be5353SAxel Dörfler			case kNextSpecifier:
598b05aa8b5SJohn Scipione			{
599ea001e58SJohn Scipione				// return entry and index of pose before or after
600ea001e58SJohn Scipione				// specified pose
601b05aa8b5SJohn Scipione				entry_ref ref;
602b05aa8b5SJohn Scipione				if (specifier->FindRef("data", &ref) != B_OK)
603b05aa8b5SJohn Scipione					break;
604db416834SMatt Madia
605b05aa8b5SJohn Scipione				int32 tmp;
606b05aa8b5SJohn Scipione				BPose* pose = FindPose(&ref, form, &tmp);
607b05aa8b5SJohn Scipione
608850b01ceSJohn Scipione				if (pose == NULL) {
609850b01ceSJohn Scipione					result = B_ENTRY_NOT_FOUND;
61002be5353SAxel Dörfler					handled = true;
61102be5353SAxel Dörfler					break;
61202be5353SAxel Dörfler				}
613db416834SMatt Madia
614b05aa8b5SJohn Scipione				reply->AddRef("result", pose->TargetModel()->EntryRef());
615b05aa8b5SJohn Scipione				reply->AddInt32("index", IndexOfPose(pose));
616b05aa8b5SJohn Scipione
617b05aa8b5SJohn Scipione				handled = true;
618b05aa8b5SJohn Scipione				break;
619b05aa8b5SJohn Scipione			}
62002be5353SAxel Dörfler		}
62102be5353SAxel Dörfler	}
622db416834SMatt Madia
623850b01ceSJohn Scipione	if (result != B_OK)
624850b01ceSJohn Scipione		reply->AddInt32("error", result);
62502be5353SAxel Dörfler
62602be5353SAxel Dörfler	return handled;
62702be5353SAxel Dörfler}
62802be5353SAxel Dörfler
629b05aa8b5SJohn Scipione
63002be5353SAxel Dörflerbool
63192dd9f73SAdrien DestuguesBPoseView::SetProperty(BMessage* message, BMessage*, int32 form,
63292dd9f73SAdrien Destugues	const char* property, BMessage* reply)
63302be5353SAxel Dörfler{
634850b01ceSJohn Scipione	status_t result = B_OK;
63502be5353SAxel Dörfler	bool handled = false;
63602be5353SAxel Dörfler
63702be5353SAxel Dörfler	if (strcmp(property, kPropertySelection) == 0) {
63802be5353SAxel Dörfler		entry_ref ref;
63902be5353SAxel Dörfler
64002be5353SAxel Dörfler		switch (form) {
64102be5353SAxel Dörfler			case B_DIRECT_SPECIFIER:
642b05aa8b5SJohn Scipione			{
643b05aa8b5SJohn Scipione				int32 selStart;
644b05aa8b5SJohn Scipione				int32 selEnd;
645b05aa8b5SJohn Scipione				if (message->FindInt32("data", 0, &selStart) == B_OK
646b05aa8b5SJohn Scipione					&& message->FindInt32("data", 1, &selEnd) == B_OK) {
647b05aa8b5SJohn Scipione					if (selStart < 0 || selStart >= fPoseList->CountItems()
648b05aa8b5SJohn Scipione						|| selEnd < 0 || selEnd >= fPoseList->CountItems()) {
649850b01ceSJohn Scipione						result = B_BAD_INDEX;
65002be5353SAxel Dörfler						handled = true;
65102be5353SAxel Dörfler						break;
65202be5353SAxel Dörfler					}
653b05aa8b5SJohn Scipione
654b05aa8b5SJohn Scipione					SelectPoses(selStart, selEnd);
655b05aa8b5SJohn Scipione					handled = true;
656b05aa8b5SJohn Scipione					break;
65702be5353SAxel Dörfler				}
658b05aa8b5SJohn Scipione			} // fall thru
65902be5353SAxel Dörfler			case kPreviousSpecifier:
66002be5353SAxel Dörfler			case kNextSpecifier:
661b05aa8b5SJohn Scipione			{
662b05aa8b5SJohn Scipione				// PRINT(("SetProperty direct/previous/next %s\n", property));
663b05aa8b5SJohn Scipione				// select/unselect poses specified by entries
664b05aa8b5SJohn Scipione				bool clearSelection = true;
665b05aa8b5SJohn Scipione				for (int32 index = 0; message->FindRef("data", index, &ref)
666850b01ceSJohn Scipione						== B_OK; index++) {
667b05aa8b5SJohn Scipione					int32 poseIndex;
668b05aa8b5SJohn Scipione					BPose* pose = FindPose(&ref, form, &poseIndex);
669ea001e58SJohn Scipione
670850b01ceSJohn Scipione					if (pose == NULL) {
671850b01ceSJohn Scipione						result = B_ENTRY_NOT_FOUND;
67202be5353SAxel Dörfler						handled = true;
673b05aa8b5SJohn Scipione						break;
67402be5353SAxel Dörfler					}
675ea001e58SJohn Scipione
676b05aa8b5SJohn Scipione					if (clearSelection) {
677ea001e58SJohn Scipione						// first selected item must call SelectPose so the
678ea001e58SJohn Scipione						// selection gets cleared first
679b05aa8b5SJohn Scipione						SelectPose(pose, poseIndex);
680b05aa8b5SJohn Scipione						clearSelection = false;
681b05aa8b5SJohn Scipione					} else
682b05aa8b5SJohn Scipione						AddPoseToSelection(pose, poseIndex);
683b05aa8b5SJohn Scipione
684b05aa8b5SJohn Scipione					handled = true;
685b05aa8b5SJohn Scipione				}
686b05aa8b5SJohn Scipione				break;
687b05aa8b5SJohn Scipione			}
688b05aa8b5SJohn Scipione		}
68902be5353SAxel Dörfler	}
69002be5353SAxel Dörfler
691850b01ceSJohn Scipione	if (result != B_OK)
692850b01ceSJohn Scipione		reply->AddInt32("error", result);
69302be5353SAxel Dörfler
69402be5353SAxel Dörfler	return handled;
69502be5353SAxel Dörfler}
69602be5353SAxel Dörfler
697b05aa8b5SJohn Scipione
698b05aa8b5SJohn ScipioneBHandler*
69992dd9f73SAdrien DestuguesBPoseView::ResolveSpecifier(BMessage* message, int32 index,
70092dd9f73SAdrien Destugues	BMessage* specifier, int32 form, const char* property)
70102be5353SAxel Dörfler{
702ea001e58SJohn Scipione	BPropertyInfo propertyInfo(
703ea001e58SJohn Scipione		const_cast<property_info*>(kPosesPropertyList));
70402be5353SAxel Dörfler
705ea001e58SJohn Scipione	int32 result = propertyInfo.FindMatch(message, index, specifier, form,
706ea001e58SJohn Scipione		property);
70702be5353SAxel Dörfler	if (result < 0) {
708ea001e58SJohn Scipione		//PRINT(("FindMatch result %d \n"));
70902be5353SAxel Dörfler		return _inherited::ResolveSpecifier(message, index, specifier,
71002be5353SAxel Dörfler			form, property);
71102be5353SAxel Dörfler	}
71202be5353SAxel Dörfler
71302be5353SAxel Dörfler	return this;
71402be5353SAxel Dörfler}
71502be5353SAxel Dörfler
716b05aa8b5SJohn Scipione
717b05aa8b5SJohn ScipioneBPose*
71892dd9f73SAdrien DestuguesBPoseView::FindPose(const entry_ref* ref, int32 specifierForm,
71992dd9f73SAdrien Destugues	int32* index) const
72002be5353SAxel Dörfler{
72102be5353SAxel Dörfler	// flavor of FindPose, used by previous/next specifiers
72202be5353SAxel Dörfler
723b05aa8b5SJohn Scipione	BPose* pose = FindPose(ref, index);
724ea001e58SJohn Scipione
72502be5353SAxel Dörfler	if (specifierForm == (int32)kPreviousSpecifier)
72602be5353SAxel Dörfler		return PoseAtIndex(--*index);
72702be5353SAxel Dörfler	else if (specifierForm == (int32)kNextSpecifier)
72802be5353SAxel Dörfler		return PoseAtIndex(++*index);
72902be5353SAxel Dörfler	else
73002be5353SAxel Dörfler		return pose;
73102be5353SAxel Dörfler}