Esempio n. 1
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;
				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;
			}
	}
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
void
TTracker::_OpenPreviouslyOpenedWindows(const char* pathFilter)
{
	size_t filterLength = 0;
	if (pathFilter != NULL)
		filterLength = strlen(pathFilter);

	BDirectory deskDir;
	attr_info attrInfo;
	if (FSGetDeskDir(&deskDir) != B_OK
		|| deskDir.GetAttrInfo(kAttrOpenWindows, &attrInfo) != B_OK)
		return;

	char *buffer = (char *)malloc((size_t)attrInfo.size);
	BMessage message;
	if (deskDir.ReadAttr(kAttrOpenWindows, B_MESSAGE_TYPE, 0, buffer,
		(size_t)attrInfo.size) != attrInfo.size
		|| message.Unflatten(buffer) != B_OK) {
		free(buffer);
		return;
	}

	free(buffer);

	node_ref nodeRef;
	deskDir.GetNodeRef(&nodeRef);

	int32 stateMessageCounter = 0;
	const char *path;
	for (int32 i = 0; message.FindString("paths", i, &path) == B_OK; i++) {
		if (strncmp(path, pathFilter, filterLength))
			continue;

		BEntry entry(path, true);
		if (entry.InitCheck() != B_OK)
			continue;

		int8 flags = 0;
		for (int32 j = 0; message.FindInt8(path, j, &flags) == B_OK; j++) {
			Model *model = new Model(&entry);
			if (model->InitCheck() == B_OK && model->IsContainer()) {
				BMessage state;
				bool restoreStateFromMessage = false;
				if ((flags & kOpenWindowHasState) != 0
					&& message.FindMessage("window state", stateMessageCounter++,
							&state) == B_OK)
					restoreStateFromMessage = true;

				if (restoreStateFromMessage) {
					OpenContainerWindow(model, 0, kOpen, kRestoreWorkspace
						| (flags & kOpenWindowMinimized ? kIsHidden : 0U)
						| kRestoreDecor, false, &state);
				} else {
					OpenContainerWindow(model, 0, kOpen, kRestoreWorkspace
						| (flags & kOpenWindowMinimized ? kIsHidden : 0U)
						| kRestoreDecor);
				}
			} else
				delete model;
		}
	}

	// Open disks window if needed

	if (pathFilter == NULL && TrackerSettings().ShowDisksIcon()
		&& message.HasBool("open_disks_window")) {
		BEntry entry("/");
		Model* model = new Model(&entry);
		if (model->InitCheck() == B_OK)
			OpenContainerWindow(model, 0, kOpen, kRestoreWorkspace);
		else
			delete model;
	}
}
Esempio n. 4
0
void
TTracker::ReadyToRun()
{
	gStatusWindow = new BStatusWindow();
	InitMimeTypes();
	InstallDefaultTemplates();
	InstallIndices();
	
	HideVarDir();

	fTrashWatcher = new BTrashWatcher();
	fTrashWatcher->Run();

	fClipboardRefsWatcher = new BClipboardRefsWatcher();
	fClipboardRefsWatcher->Run();
	
	fAutoMounter = new AutoMounter();
	fAutoMounter->Run();
	
	fTaskLoop = new StandAloneTaskLoop(true);

	bool openDisksWindow = false;

	// open desktop window 
	BContainerWindow *deskWindow = NULL;
	BVolume	bootVol;
	BVolumeRoster().GetBootVolume(&bootVol);
	BDirectory deskDir;
	if (FSGetDeskDir(&deskDir, bootVol.Device()) == B_OK) {
		// create desktop
		BEntry entry;
		deskDir.GetEntry(&entry);
		Model *model = new Model(&entry);
		if (model->InitCheck() == B_OK) {
			AutoLock<WindowList> lock(&fWindowList);
			deskWindow = new BDeskWindow(&fWindowList);
			AutoLock<BWindow> windowLock(deskWindow);
			deskWindow->CreatePoseView(model);
			deskWindow->Init();
		} else
			delete model;

		// open previously open windows
		attr_info attrInfo;
		if (!BootedInSafeMode()
			&& deskDir.GetAttrInfo(kAttrOpenWindows, &attrInfo) == B_OK) {
			char *buffer = (char *)malloc((size_t)attrInfo.size);
			BMessage message;
			if (deskDir.ReadAttr(kAttrOpenWindows, B_MESSAGE_TYPE, 0, buffer, (size_t)attrInfo.size)
				== attrInfo.size
				&& message.Unflatten(buffer) == B_OK) {

				node_ref nodeRef;
				deskDir.GetNodeRef(&nodeRef);
	
				int32 stateMessageCounter = 0;
				const char *path;
				for (int32 outer = 0;message.FindString("paths", outer, &path) == B_OK;outer++) {
					int8 flags = 0;
					for (int32 inner = 0;message.FindInt8(path, inner, &flags) == B_OK;inner++) {
						BEntry entry(path, true);
						if (entry.InitCheck() == B_OK) {
							Model *model = new Model(&entry);
							if (model->InitCheck() == B_OK && model->IsContainer()) {
								BMessage state;
								bool restoreStateFromMessage = false;
								if ((flags & kOpenWindowHasState) != 0
									&& message.FindMessage("window state", stateMessageCounter++, &state) == B_OK)
									restoreStateFromMessage = true;

								if (restoreStateFromMessage)
									OpenContainerWindow(model, 0, kOpen, 
										kRestoreWorkspace | (flags & kOpenWindowMinimized ? kIsHidden : 0U),
										false, &state);
								else
									OpenContainerWindow(model, 0, kOpen, 
										kRestoreWorkspace | (flags & kOpenWindowMinimized ? kIsHidden : 0U));
							} else
								delete model;
						}
					}
				}
	
				if (message.HasBool("open_disks_window"))
					openDisksWindow = true;
			}
			free(buffer);
		}
	}

	// create model for root of everything
	if (deskWindow) {
		BEntry entry("/");
		Model model(&entry);
		if (model.InitCheck() == B_OK) {

			if (TrackerSettings().ShowDisksIcon()) {
				// add the root icon to desktop window
				BMessage message;
				message.what = B_NODE_MONITOR;
				message.AddInt32("opcode", B_ENTRY_CREATED);
				message.AddInt32("device", model.NodeRef()->device);
				message.AddInt64("node", model.NodeRef()->node);
				message.AddInt64("directory", model.EntryRef()->directory);
				message.AddString("name", model.EntryRef()->name);
				deskWindow->PostMessage(&message, deskWindow->PoseView());
			}
			
			if (openDisksWindow)
				OpenContainerWindow(new Model(model), 0, kOpen, kRestoreWorkspace);
		}
	}

	// kick off building the mime type list for find panels, etc.
	fMimeTypeList = new MimeTypeList();

	if (!BootedInSafeMode())
		// kick of transient query killer
		DeleteTransientQueriesTask::StartUpTransientQueryCleaner();
}
Esempio n. 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;
		}
	}
}