예제 #1
0
파일: BarApp.cpp 프로젝트: kbjava/haiku
void
TBarApp::RefsReceived(BMessage* refs)
{
	entry_ref ref;
	for (int32 i = 0; refs->FindRef("refs", i, &ref) == B_OK; i++) {
		BMessage refsReceived(B_REFS_RECEIVED);
		refsReceived.AddRef("refs", &ref);

		BEntry entry(&ref);
		if (!entry.IsDirectory())
			TrackerLaunch(&refsReceived, false);
	}
}
예제 #2
0
파일: Tracker.cpp 프로젝트: Ithamar/cosmoe
bool 
TTracker::LaunchAndCloseParentIfOK(const entry_ref *launchThis,
	const node_ref *closeThis, const BMessage *messageToBundle)
{
	BMessage refsReceived(B_REFS_RECEIVED);
	if (messageToBundle) {
		refsReceived = *messageToBundle;
		refsReceived.what = B_REFS_RECEIVED;
	}
	refsReceived.AddRef("refs", launchThis);	
	// synchronous launch, we are already in our own thread
	if (TrackerLaunch(&refsReceived, false) == B_OK) {
		// if launched fine, close parent window in a bit
		fTaskLoop->RunLater(NewMemberFunctionObject(&TTracker::CloseParent, this, *closeThis),
			1000000);
	}
	return false;
}
예제 #3
0
파일: Tracker.cpp 프로젝트: Ithamar/cosmoe
void
TTracker::RefsReceived(BMessage *message)
{
	OpenSelector selector = kOpen;
	if (message->HasInt32("launchUsingSelector"))
		selector = kRunOpenWithWindow;

	entry_ref handlingApp;
	if (message->FindRef("handler", &handlingApp) == B_OK)
		selector = kOpenWith;

	int32 count;
	uint32 type;
	message->GetInfo("refs", &type, &count);

	switch (selector) {
		case kRunOpenWithWindow:
			OpenContainerWindow(0, message, selector);
				// window adopts model
			break;

		case kOpenWith:
			{
				// Open With resulted in passing refs and a handler, open the files
				// with the handling app
				message->RemoveName("handler");

				// have to find out if handling app is the Tracker
				// if it is, just pass it to the active Tracker, no matter which Tracker
				// was chosen to handle the refs
				char signature[B_MIME_TYPE_LENGTH];
				signature[0] = '\0';
				{
					BFile handlingNode(&handlingApp, O_RDONLY);
					BAppFileInfo appInfo(&handlingNode);
					appInfo.GetSignature(signature);
				}

				if (strcasecmp(signature, kTrackerSignature) != 0) {
					// handling app not Tracker, pass entries to the apps RefsReceived
					TrackerLaunch(&handlingApp, message, true);
					break;
				}
				// fall thru, opening refs by the Tracker, as if they were double clicked
			}

		case kOpen:
			{
				// copy over "Poses" messenger so that refs received recipients know
				// where the open came from
				BMessage *bundleThis = NULL;
				BMessenger messenger;
				if (message->FindMessenger("TrackerViewToken", &messenger) == B_OK) {
					bundleThis = new BMessage();
					bundleThis->AddMessenger("TrackerViewToken", messenger);
				}

				for (int32 index = 0; index < count; index++) {
					entry_ref ref;
					message->FindRef("refs", index, &ref);

					const node_ref *nodeToClose = NULL;
					const node_ref *nodeToSelect = NULL;
					ssize_t numBytes;

					message->FindData("nodeRefsToClose", B_RAW_TYPE, index,
						(const void **)&nodeToClose, &numBytes);
					message->FindData("nodeRefToSelect", B_RAW_TYPE, index,
						(const void **)&nodeToSelect, &numBytes);

					OpenRef(&ref, nodeToClose, nodeToSelect, selector, bundleThis);
				}

				delete bundleThis;
				break;
			}
	}
}
예제 #4
0
파일: Tracker.cpp 프로젝트: Ithamar/cosmoe
status_t
TTracker::OpenRef(const entry_ref *ref, const node_ref *nodeToClose,
	const node_ref *nodeToSelect, OpenSelector selector,
	const BMessage *messageToBundle)
{
	Model *model = NULL;
	BEntry entry(ref, true);
	status_t result = entry.InitCheck();

	bool brokenLinkWithSpecificHandler = false;
	BString brokenLinkPreferredApp;

	if (result != B_OK) {
		model = new Model(ref, false);
		if (model->IsSymLink() && !model->LinkTo()) {
			model->GetPreferredAppForBrokenSymLink(brokenLinkPreferredApp);
			if (brokenLinkPreferredApp.Length() && brokenLinkPreferredApp != kTrackerSignature)
				brokenLinkWithSpecificHandler = true;
		}

		if (!brokenLinkWithSpecificHandler) {
			delete model;
			(new BAlert("", "There was an error resolving the link.",
				"Cancel", 0, 0,
				B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go();
			return result;
		}
	} else 
		model = new Model(&entry);

	result = model->InitCheck();
	if (result != B_OK) {
		delete model;
		return result;
	}

	bool openAsContainer = model->IsContainer();

	if (openAsContainer && selector != kOpenWith) {
		// if folder or query has a preferred handler and it's not the
		// Tracker, open it by sending refs to the handling app

		// if we are responding to the final open of OpenWith, just
		// skip this and proceed to opening the container with Tracker
		model->OpenNode();
		BNodeInfo nodeInfo(model->Node());
		char preferredApp[B_MIME_TYPE_LENGTH];
		if (nodeInfo.GetPreferredApp(preferredApp) == B_OK
			&& strcasecmp(preferredApp, kTrackerSignature) != 0)
			openAsContainer = false;
		model->CloseNode();
	}

	if (openAsContainer || selector == kRunOpenWithWindow) {
		// special case opening plain folders, queries or using open with
		OpenContainerWindow(model, 0, selector);	// window adopts model
		if (nodeToClose)
			CloseParentWaitingForChildSoon(ref, nodeToClose);
	} else if (model->IsQueryTemplate()) {
		// query template - open new find window
		(new FindWindow(model->EntryRef()))->Show();
		if (nodeToClose)
			CloseParentWaitingForChildSoon(ref, nodeToClose);
	} else {
		delete model;
		// run Launch in a separate thread
		// and close parent if successfull
		if (nodeToClose)
			Thread::Launch(new EntryAndNodeDoSoonWithMessageFunctor<TTracker,
				bool (TTracker::*)(const entry_ref *, const node_ref *,
				const BMessage *)>(&TTracker::LaunchAndCloseParentIfOK, this,
				ref, nodeToClose, messageToBundle));
		else {
			BMessage refsReceived(B_REFS_RECEIVED);
			if (messageToBundle) {
				refsReceived = *messageToBundle;
				refsReceived.what = B_REFS_RECEIVED;
			}
			refsReceived.AddRef("refs", ref);
			if (brokenLinkWithSpecificHandler)
				// This cruft is to support a hacky workaround for double-clicking
				// broken refs for cifs; should get fixed in R5
				LaunchBrokenLink(brokenLinkPreferredApp.String(), &refsReceived);
			else
				TrackerLaunch(&refsReceived, true);
		}
	}
	if (nodeToSelect)
		SelectChildInParentSoon(ref, nodeToSelect);

	return B_OK;
}
예제 #5
0
void
TTracker::RefsReceived(BMessage* message)
{
	OpenSelector selector = kOpen;
	if (message->HasInt32("launchUsingSelector"))
		selector = kRunOpenWithWindow;

	entry_ref handlingApp;
	if (message->FindRef("handler", &handlingApp) == B_OK)
		selector = kOpenWith;

	int32 count;
	uint32 type;
	message->GetInfo("refs", &type, &count);

	switch (selector) {
		case kRunOpenWithWindow:
			OpenContainerWindow(0, message, selector);
				// window adopts model
			break;

		case kOpenWith:
		{
			// Open With resulted in passing refs and a handler,
			// open the files with the handling app
			message->RemoveName("handler");

			// have to find out if handling app is the Tracker
			// if it is, just pass it to the active Tracker,
			// no matter which Tracker was chosen to handle the refs
			char signature[B_MIME_TYPE_LENGTH];
			signature[0] = '\0';
			{
				BFile handlingNode(&handlingApp, O_RDONLY);
				BAppFileInfo appInfo(&handlingNode);
				appInfo.GetSignature(signature);
			}

			if (strcasecmp(signature, kTrackerSignature) != 0) {
				// handling app not Tracker, pass entries to the apps
				// RefsReceived
				TrackerLaunch(&handlingApp, message, true);
				break;
			}
		}
		// fall thru, opening refs by the Tracker as if they were
		// double-clicked
		case kOpen:
		{
			// copy over "Poses" messenger so that refs received
			// recipients know where the open came from
			BMessage* bundleThis = NULL;
			BMessage stackBundleThis;
			BMessenger messenger;
			if (message->FindMessenger("TrackerViewToken", &messenger)
					== B_OK) {
				bundleThis = &stackBundleThis;
				bundleThis->AddMessenger("TrackerViewToken", messenger);
			} else {
				// copy over any "be:*" fields -- e.g. /bin/open may include
				// "be:line" and "be:column"
				for (int32 i = 0;; i++) {
					char* name;
					type_code type;
					int32 count;
					status_t error = message->GetInfo(B_ANY_TYPE, i, &name,
						&type, &count);
					if (error != B_OK)
						break;

					if (strncmp(name, "be:", 3) != 0)
						continue;

					for (int32 k = 0; k < count; k++) {
						const void* data;
						ssize_t size;
						if (message->FindData(name, type, k, &data, &size)
								!= B_OK) {
							break;
						}
						if (stackBundleThis.AddData(name, type, data, size)
								!= B_OK) {
							break;
						}
						bundleThis = &stackBundleThis;
					}
				}
			}

			for (int32 index = 0; index < count; index++) {
				entry_ref ref;
				message->FindRef("refs", index, &ref);

				const node_ref* nodeToClose = NULL;
				const node_ref* nodeToSelect = NULL;
				ssize_t numBytes;

				message->FindData("nodeRefsToClose", B_RAW_TYPE, index,
					(const void**)&nodeToClose, &numBytes);
				message->FindData("nodeRefToSelect", B_RAW_TYPE, index,
					(const void**)&nodeToSelect, &numBytes);

				OpenRef(&ref, nodeToClose, nodeToSelect, selector,
					bundleThis);
			}

			break;
		}
	}
}