Beispiel #1
0
bool
TFilePanel::SwitchDirToDesktopIfNeeded(entry_ref &ref)
{
	// support showing Desktop as root of everything
	// This call implements the worm hole that maps Desktop as
	// a root above the disks
	TrackerSettings settings;
	if (!settings.DesktopFilePanelRoot())
		// Tracker isn't set up that way, just let Disks show
		return false;

	BEntry entry(&ref);
	BEntry root("/");

	BDirectory desktopDir;
	FSGetDeskDir(&desktopDir);
	if (FSIsDeskDir(&entry)
		// navigated into non-boot desktop, switch to boot desktop
		|| (entry == root && !settings.ShowDisksIcon())) {
		// hit "/" level, map to desktop

		desktopDir.GetEntry(&entry);
		entry.GetRef(&ref);
		return true;
	}
	return FSIsDeskDir(&entry);
}
Beispiel #2
0
bool
TTracker::QuitRequested()
{
	// don't allow user quitting
	if (CurrentMessage() && CurrentMessage()->FindBool("shortcut"))
		return false;

	gStatusWindow->AttemptToQuit();
		// try quitting the copy/move/empty trash threads
		
	BVolume bootVolume;
	DEBUG_ONLY(status_t err =) BVolumeRoster().GetBootVolume(&bootVolume);
	ASSERT(err == B_OK);
	BMessage message;
	AutoLock<WindowList> lock(&fWindowList);
	// save open windows in a message inside an attribute of the desktop
	int32 count = fWindowList.CountItems();
	for (int32 i = 0; i < count; i++) {
		BContainerWindow *window = dynamic_cast<BContainerWindow *>
			(fWindowList.ItemAt(i));

		if (window && window->TargetModel() && !window->PoseView()->IsDesktopWindow()) {
			if (window->TargetModel()->IsRoot())
				message.AddBool("open_disks_window", true);
			else {
				BEntry entry;
				BPath path;
				const entry_ref *ref = window->TargetModel()->EntryRef();
				if (entry.SetTo(ref) == B_OK && entry.GetPath(&path) == B_OK) {
					int8 flags = window->IsMinimized() ? kOpenWindowMinimized : kOpenWindowNoFlags;
					uint32 deviceFlags = GetVolumeFlags(window->TargetModel());

					// save state for every window which is
					//	a) already open on another workspace
					//	b) on a volume not capable of writing attributes
					if (window != FindContainerWindow(ref)
						|| (deviceFlags & (B_FS_HAS_ATTR | B_FS_IS_READONLY)) != B_FS_HAS_ATTR) {
						BMessage stateMessage;
						window->SaveState(stateMessage);
						window->SetSaveStateEnabled(false);
							// This is to prevent its state to be saved to the node when closed.
						message.AddMessage("window state", &stateMessage);
						flags |= kOpenWindowHasState;
					}
					const char *target;
					bool pathAlreadyExists = false;
					for (int32 index = 0;message.FindString("paths", index, &target) == B_OK;index++) {
						if (!strcmp(target,path.Path())) {
							pathAlreadyExists = true;
							break;
						}
					}
					if (!pathAlreadyExists)
						message.AddString("paths", path.Path());
					message.AddInt8(path.Path(), flags);
				}
			}	
		}
	}
	lock.Unlock();

	// write windows to open on disk
	BDirectory deskDir;
	if (!BootedInSafeMode() && FSGetDeskDir(&deskDir, bootVolume.Device()) == B_OK) {
		// if message is empty, delete the corresponding attribute
		if (message.CountNames(B_ANY_TYPE)) {
			size_t size = (size_t)message.FlattenedSize();
			char *buffer = new char[size];
			message.Flatten(buffer, (ssize_t)size);
			deskDir.WriteAttr(kAttrOpenWindows, B_MESSAGE_TYPE, 0, buffer, size);
			delete [] buffer;
		} else
			deskDir.RemoveAttr(kAttrOpenWindows);
	}

	for (int32 count = 0; count == 50; count++) {
		// wait 5 seconds for the copiing/moving to quit
		if (gStatusWindow->AttemptToQuit())
			break;

		snooze(100000);
	}

	return _inherited::QuitRequested();
}
Beispiel #3
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();
}
Beispiel #4
0
void
BDirMenu::Populate(const BEntry* startEntry, BWindow* originatingWindow,
	bool includeStartEntry, bool select, bool reverse, bool addShortcuts,
	bool navMenuEntries)
{
	try {
		if (!startEntry)
			throw (status_t)B_ERROR;

		Model model(startEntry);
		ThrowOnInitCheckError(&model);

		ModelMenuItem* menu = new ModelMenuItem(&model, this, true, true);

		if (fMenuBar)
			fMenuBar->AddItem(menu);

		BEntry entry(*startEntry);

		bool showDesktop, showDisksIcon;
		{
			TrackerSettings settings;
			showDesktop = settings.DesktopFilePanelRoot();
			showDisksIcon = settings.ShowDisksIcon();
		}

		// might start one level above startEntry
		if (!includeStartEntry) {
			BDirectory parent;
			BDirectory dir(&entry);

			if (!showDesktop && dir.InitCheck() == B_OK
				&& dir.IsRootDirectory()) {
				// if we're at the root directory skip "mnt" and
				// go straight to "/"
				parent.SetTo("/");
			} else
				entry.GetParent(&parent);

			parent.GetEntry(&entry);
		}

		BDirectory desktopDir;
		FSGetDeskDir(&desktopDir);
		BEntry desktopEntry;
		desktopDir.GetEntry(&desktopEntry);

		for (;;) {
			BNode node(&entry);
			ThrowOnInitCheckError(&node);

			PoseInfo info;
			ReadAttrResult result = ReadAttr(&node, kAttrPoseInfo,
				kAttrPoseInfoForeign, B_RAW_TYPE, 0, &info, sizeof(PoseInfo),
				&PoseInfo::EndianSwap);

			BDirectory parent;
			entry.GetParent(&parent);

			bool hitRoot = false;

			BDirectory dir(&entry);
			if (!showDesktop && dir.InitCheck() == B_OK
				&& dir.IsRootDirectory()) {
				// if we're at the root directory skip "mnt" and
				// go straight to "/"
				hitRoot = true;
				parent.SetTo("/");
			}

			if (showDesktop) {
				BEntry root("/");
				// warp from "/" to Desktop properly
				if (entry == root) {
					if (showDisksIcon)
						AddDisksIconToMenu(reverse);
					entry = desktopEntry;
				}

				if (entry == desktopEntry)
					hitRoot = true;
			}

			if (result == kReadAttrFailed || !info.fInvisible
				|| (showDesktop && desktopEntry == entry)) {
				AddItemToDirMenu(&entry, originatingWindow, reverse,
					addShortcuts, navMenuEntries);
			}

			if (hitRoot) {
				if (!showDesktop && showDisksIcon && *startEntry != "/")
					AddDisksIconToMenu(reverse);
				break;
			}

			parent.GetEntry(&entry);
		}

		// select last item in menu
		if (!select)
			return;

		ModelMenuItem* item
			= dynamic_cast<ModelMenuItem*>(ItemAt(CountItems() - 1));
		if (item) {
			item->SetMarked(true);
			if (menu) {
				entry.SetTo(item->TargetModel()->EntryRef());
				ThrowOnError(menu->SetEntry(&entry));
			}
		}
	} catch (status_t err) {
		PRINT(("BDirMenu::Populate: caught error %s\n", strerror(err)));
		if (!CountItems()) {
			BString error;
			error << "Error [" << strerror(err) << "] populating menu";
			AddItem(new BMenuItem(error.String(), 0));
		}
	}
}
Beispiel #5
0
void
TTracker::ReadyToRun()
{
	gStatusWindow = new BStatusWindow();
	InitMimeTypes();
	InstallDefaultTemplates();
	InstallIndices();
	InstallTemporaryBackgroundImages();

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

	fClipboardRefsWatcher = new BClipboardRefsWatcher();
	fClipboardRefsWatcher->Run();

	fTaskLoop = new StandAloneTaskLoop(true);

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

			if (TrackerSettings().ShowDisksIcon()) {
				// create model for root of everything
				BEntry entry("/");
				Model model(&entry);
				if (model.InitCheck() == B_OK) {
					// 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());
				}
			}
		} else
			delete model;
	}

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

	if (!BootedInSafeMode()) {
		// kick of transient query killer
		DeleteTransientQueriesTask::StartUpTransientQueryCleaner();
		// the mount_server will have mounted the previous volumes already.
		_OpenPreviouslyOpenedWindows();
	}
}
Beispiel #6
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;
	}
}
Beispiel #7
0
TTracker::TTracker()
	:
	BApplication(kTrackerSignature),
	fMimeTypeList(NULL),
	fClipboardRefsWatcher(NULL),
	fTrashWatcher(NULL),
	fTaskLoop(NULL),
	fNodeMonitorCount(-1),
	fWatchingInterface(new WatchingInterface),
	fSettingsWindow(NULL)
{
	BPathMonitor::SetWatchingInterface(fWatchingInterface);

	// set the cwd to /boot/home, anything that's launched
	// from Tracker will automatically inherit this
	BPath homePath;

	if (find_directory(B_USER_DIRECTORY, &homePath) == B_OK)
		chdir(homePath.Path());

	// ask for a bunch more file descriptors so that nested copying works well
	struct rlimit rl;
	rl.rlim_cur = 512;
	rl.rlim_max = RLIM_SAVED_MAX;
	setrlimit(RLIMIT_NOFILE, &rl);

	fNodeMonitorCount = DEFAULT_MON_NUM;

	gLocalizedNamePreferred
		= BLocaleRoster::Default()->IsFilesystemTranslationPreferred();

#ifdef CHECK_OPEN_MODEL_LEAKS
	InitOpenModelDumping();
#endif

	InitIconPreloader();

#ifdef LEAK_CHECKING
	SetNewLeakChecking(true);
	SetMallocLeakChecking(true);
#endif

	// This is how often it should update the free space bar on the
	// volume icons
	SetPulseRate(1000000);

	gLaunchLooper = new LaunchLooper();
	gLaunchLooper->Run();

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

			if (TrackerSettings().ShowDisksIcon()) {
				// create model for root of everything
				BEntry entry("/");
				Model model(&entry);
				if (model.InitCheck() == B_OK) {
					// 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());
				}
			}
		} else
			delete model;
	}
}