Esempio n. 1
0
void
BPose::UpdateBrokenSymLink(BPoint poseLoc, BPoseView* poseView)
{
	ASSERT(TargetModel()->IsSymLink());
	ASSERT(!TargetModel()->LinkTo());

	if (!TargetModel()->IsSymLink() || TargetModel()->LinkTo())
		return;

	UpdateIcon(poseLoc, poseView);
}
Esempio n. 2
0
void
TFilePanel::ShowContextMenu(BPoint point, const entry_ref* ref, BView* view)
{
	EnableNamedMenuItem(fWindowContextMenu, kNewFolder,
		!TargetModel()->IsRoot());
	EnableNamedMenuItem(fWindowContextMenu, kOpenParentDir,
		!TargetModel()->IsRoot());
	EnableNamedMenuItem(fWindowContextMenu, kMoveToTrash,
		!TargetModel()->IsRoot());

	_inherited::ShowContextMenu(point, ref, view);
}
Esempio n. 3
0
void
BFilePanelPoseView::ShowVolumes(bool visible, bool showShared)
{
	if (IsDesktopView()) {
		if (!visible)
			RemoveRootPoses();
		else
			AddRootPoses(true, showShared);
	}

	TFilePanel* filepanel = dynamic_cast<TFilePanel*>(Window());
	if (filepanel != NULL && TargetModel() != NULL)
		filepanel->SetTo(TargetModel()->EntryRef());
}
Esempio n. 4
0
bool
TFilePanel::CanOpenParent() const
{
	if (TrackerSettings().DesktopFilePanelRoot()) {
		// don't allow opening Desktop folder's parent
		if (TargetModel()->IsDesktop())
			return false;
	}

	// block on "/"
	BEntry root("/");
	node_ref rootRef;
	root.GetNodeRef(&rootRef);

	return rootRef != *TargetModel()->NodeRef();
}
Esempio n. 5
0
void
TFilePanel::OpenSelectionCommon(BMessage* openMessage)
{
	if (!openMessage->HasRef("refs"))
		return;

	for (int32 index = 0; ; index++) {
		entry_ref ref;
		if (openMessage->FindRef("refs", index, &ref) != B_OK)
			break;

		BEntry entry(&ref, true);
		if (entry.InitCheck() == B_OK) {
			if (entry.IsDirectory())
				BRoster().AddToRecentFolders(&ref);
			else
				BRoster().AddToRecentDocuments(&ref);
		}
	}

	BRoster().AddToRecentFolders(TargetModel()->EntryRef());

	if (fClientObject)
		fClientObject->SendMessage(&fTarget, openMessage);
	else
		fTarget.SendMessage(openMessage);

	// close window if we're dealing with standard message
	if (fHideWhenDone)
		PostMessage(B_QUIT_REQUESTED);
}
Esempio n. 6
0
bool
BFilePanelPoseView::FSNotification(const BMessage* message)
{
	if (IsDesktopView()) {
		// Pretty much copied straight from DesktopPoseView.
		// Would be better if the code could be shared somehow.
		switch (message->FindInt32("opcode")) {
			case B_DEVICE_MOUNTED:
			{
				dev_t device;
				if (message->FindInt32("new device", &device) != B_OK)
					break;

				ASSERT(TargetModel() != NULL);
				TrackerSettings settings;

				BVolume volume(device);
				if (volume.InitCheck() != B_OK)
					break;

				if (settings.MountVolumesOntoDesktop()
					&& (!volume.IsShared()
						|| settings.MountSharedVolumesOntoDesktop())) {
					// place an icon for the volume onto the desktop
					CreateVolumePose(&volume, true);
				}
			}
			break;
		}
	}
	return _inherited::FSNotification(message);
}
Esempio n. 7
0
bool
DesktopPoseView::FSNotification(const BMessage* message)
{
    switch (message->FindInt32("opcode")) {
    case B_DEVICE_MOUNTED:
    {
        dev_t device;
        if (message->FindInt32("new device", &device) != B_OK)
            break;

        ASSERT(TargetModel());
        TrackerSettings settings;

        BVolume volume(device);
        if (volume.InitCheck() != B_OK)
            break;

        if (settings.MountVolumesOntoDesktop()
                && (!volume.IsShared()
                    || settings.MountSharedVolumesOntoDesktop())) {
            // place an icon for the volume onto the desktop
            CreateVolumePose(&volume, true);
        }
    }
    break;
    }

    return _inherited::FSNotification(message);
}
Esempio n. 8
0
void
TFilePanel::MenusBeginning()
{
	int32 count = PoseView()->SelectionList()->CountItems();

	EnableNamedMenuItem(fMenuBar, kNewFolder, !TargetModel()->IsRoot());
	EnableNamedMenuItem(fMenuBar, kMoveToTrash, !TargetModel()->IsRoot()
		&& count);
	EnableNamedMenuItem(fMenuBar, kGetInfo, count != 0);
	EnableNamedMenuItem(fMenuBar, kEditItem, count == 1);

	SetCutItem(fMenuBar);
	SetCopyItem(fMenuBar);
	SetPasteItem(fMenuBar);

	fIsTrackingMenu = true;
}
bool
VirtualDirectoryPoseView::_NodeStatChanged(const BMessage* message)
{
	node_ref nodeRef;
	if (message->FindInt32("device", &nodeRef.device) != B_OK
		|| message->FindInt64("node", &nodeRef.node) != B_OK) {
		return true;
	}

	if (nodeRef == fRootDefinitionFileRef) {
		if ((message->GetInt32("fields", 0) & B_STAT_MODIFICATION_TIME) != 0) {
			VirtualDirectoryManager* manager
				= VirtualDirectoryManager::Instance();
			if (manager != NULL) {
				AutoLocker<VirtualDirectoryManager> managerLocker(manager);
				if (!manager->DefinitionFileChanged(
						*TargetModel()->NodeRef())) {
					// The definition file no longer exists. Ignore the message
					// -- we'll get a remove notification soon.
					return true;
				}

				bigtime_t fileChangeTime;
				manager->GetDefinitionFileChangeTime(*TargetModel()->NodeRef(),
					fileChangeTime);
				if (fileChangeTime != fFileChangeTime) {
					_UpdateDirectoryPaths();
					managerLocker.Unlock();
					Refresh();
						// TODO: Refresh() is rather radical. Or rather its
						// implementation is. Ideally it would just compare the
						// currently added poses with what a new dir iterator
						// returns and remove/add poses as needed.
				}
			}
		}

		if (!fIsRoot)
			return true;
	}

	return _inherited::FSNotification(message);
}
EntryListBase*
VirtualDirectoryPoseView::InitDirentIterator(const entry_ref* ref)
{
	if (fRootDefinitionFileRef.node < 0 || *ref != *TargetModel()->EntryRef())
		return NULL;

	Model sourceModel(ref, false, true);
	if (sourceModel.InitCheck() != B_OK)
		return NULL;

	VirtualDirectoryEntryList* entryList
		= new(std::nothrow) VirtualDirectoryEntryList(
			*TargetModel()->NodeRef(), fDirectoryPaths);
	if (entryList == NULL || entryList->InitCheck() != B_OK) {
		delete entryList;
		return NULL;
	}

	return entryList;
}
status_t
VirtualDirectoryPoseView::_UpdateDirectoryPaths()
{
	VirtualDirectoryManager* manager = VirtualDirectoryManager::Instance();
	Model* model = TargetModel();
	status_t error = manager->ResolveDirectoryPaths(*model->NodeRef(),
		*model->EntryRef(), fDirectoryPaths);
	if (error != B_OK)
		return error;

	manager->GetDefinitionFileChangeTime(*model->NodeRef(), fFileChangeTime);
	return B_OK;
}
void
VirtualDirectoryPoseView::StartWatching()
{
	// watch the directories
	int32 count = fDirectoryPaths.CountStrings();
	for (int32 i = 0; i < count; i++) {
		BString path = fDirectoryPaths.StringAt(i);
		BPathMonitor::StartWatching(path, B_WATCH_DIRECTORY, this);
	}

	// watch the definition file
	TTracker::WatchNode(TargetModel()->NodeRef(),
		B_WATCH_NAME | B_WATCH_STAT | B_WATCH_ATTR, this);

	// also watch the root definition file
	if (!fIsRoot)
		TTracker::WatchNode(&fRootDefinitionFileRef, B_WATCH_STAT, this);
}
Esempio n. 13
0
void InstanceDlg::OnBrowseModelFile( wxCommandEvent &event )
{
	wxString filter = _("3D Model files");
	filter += _T("|");
	AddType(filter, FSTRING_3DS);
	AddType(filter, FSTRING_DAE);
	AddType(filter, FSTRING_OBJ);
	AddType(filter, FSTRING_LWO);
	AddType(filter, FSTRING_FLT);
	AddType(filter, FSTRING_OSG);
	AddType(filter, FSTRING_IVE);
	filter += _T("|");
	filter += FSTRING_ALL;
	wxFileDialog SelectFile(this, _("Choose model file"),
							_T(""), _T(""), filter, wxFD_OPEN);
	if (SelectFile.ShowModal() != wxID_OK)
		return;

	// If model file can be found by mimicing the search strategy implemented by
	// vtStructInstance3d::CreateNode then remove the directory part of the path
	// so that paths are not stored unnecessarily
	wxFileName TargetModel(SelectFile.GetPath());
	wxString filepart = TargetModel.GetFullName();
	vtString FoundModel = FindFileOnPaths(vtGetDataPath(), filepart.mb_str(wxConvUTF8));
	if ("" != FoundModel)
	{
		GetModelFile()->SetValue(filepart);
		return;
	}
	wxString test = wxT("BuildingModels/") + filepart;
	FoundModel = FindFileOnPaths(vtGetDataPath(), test.mb_str(wxConvUTF8));
	if ("" != FoundModel)
	{
		GetModelFile()->SetValue(filepart);
		return;
	}
	// Otherwise, use the full absolute path
	GetModelFile()->SetValue(SelectFile.GetPath());
}
Esempio n. 14
0
void
BPose::PrintToStream()
{
	TargetModel()->PrintToStream();
	switch (fClipboardMode) {
		case kMoveSelectionTo:
			PRINT(("clipboardMode: Cut\n"));
			break;

		case kCopySelectionTo:
			PRINT(("clipboardMode: Copy\n"));
			break;

		default:
			PRINT(("clipboardMode: 0 - not in clipboard\n"));
			break;
	}
	PRINT(("%sselected\n", IsSelected() ? "" : "not "));
	PRINT(("location %s x:%f y:%f\n", HasLocation() ? "" : "unknown ",
		HasLocation() ? fLocation.x : 0,
		HasLocation() ? fLocation.y : 0));
	PRINT(("%s autoplaced \n", WasAutoPlaced() ? "was" : "not"));
}
Esempio n. 15
0
void
TFilePanel::Init(const BMessage*)
{
	BRect windRect(Bounds());
	AddChild(fBackView = new BackgroundView(windRect));

	// add poseview menu bar
	fMenuBar = new BMenuBar(BRect(0, 0, windRect.Width(), 1), "MenuBar");
	fMenuBar->SetBorder(B_BORDER_FRAME);
	fBackView->AddChild(fMenuBar);

	AddMenus();
	AddContextMenus();

	FavoritesMenu* favorites = new FavoritesMenu(B_TRANSLATE("Favorites"),
		new BMessage(kSwitchDirectory), new BMessage(B_REFS_RECEIVED),
		BMessenger(this), IsSavePanel(), fPoseView->RefFilter());
	favorites->AddItem(new BMenuItem(B_TRANSLATE("Add current folder"),
		new BMessage(kAddCurrentDir)));
	favorites->AddItem(new BMenuItem(
		B_TRANSLATE("Edit favorites" B_UTF8_ELLIPSIS),
		new BMessage(kEditFavorites)));

	fMenuBar->AddItem(favorites);

	// configure menus
	BMenuItem* item = fMenuBar->FindItem(B_TRANSLATE("Window"));
	if (item) {
		fMenuBar->RemoveItem(item);
		delete item;
	}

	item = fMenuBar->FindItem(B_TRANSLATE("File"));
	if (item) {
		BMenu* menu = item->Submenu();
		if (menu) {
			item = menu->FindItem(kOpenSelection);
			if (item && menu->RemoveItem(item))
				delete item;

			item = menu->FindItem(kDuplicateSelection);
			if (item && menu->RemoveItem(item))
				delete item;

			// remove add-ons menu, identifier menu, separator
			item = menu->FindItem(B_TRANSLATE("Add-ons"));
			if (item) {
				int32 index = menu->IndexOf(item);
				delete menu->RemoveItem(index);
				delete menu->RemoveItem(--index);
				delete menu->RemoveItem(--index);
			}

			// remove separator
			item = menu->FindItem(B_CUT);
			if (item) {
				item = menu->ItemAt(menu->IndexOf(item)-1);
				if (item && menu->RemoveItem(item))
					delete item;
			}
		}
	}

	// add directory menu and menufield
	fDirMenu = new BDirMenu(0, this, kSwitchDirectory, "refs");

	font_height ht;
	be_plain_font->GetHeight(&ht);
	float f_height = ht.ascent + ht.descent + ht.leading;

	BRect rect;
	rect.top = fMenuBar->Bounds().Height() + 8;
	rect.left = windRect.left + 8;
	rect.right = rect.left + 300;
	rect.bottom = rect.top + (f_height > 22 ? f_height : 22);

	fDirMenuField = new BMenuField(rect, "DirMenuField", "", fDirMenu);
	fDirMenuField->MenuBar()->SetFont(be_plain_font);
	fDirMenuField->SetDivider(0);
	fDirMenuField->MenuBar()->SetMaxContentWidth(rect.Width() - 26.0f);
		// Make room for the icon

	fDirMenuField->MenuBar()->RemoveItem((int32)0);
	fDirMenu->SetMenuBar(fDirMenuField->MenuBar());
		// the above is a weird call from BDirMenu
		// ToDo: clean up

	BEntry entry(TargetModel()->EntryRef());
	if (entry.InitCheck() == B_OK)
		fDirMenu->Populate(&entry, 0, true, true, false, true);
	else
		fDirMenu->Populate(0, 0, true, true, false, true);

	fBackView->AddChild(fDirMenuField);

	// add file name text view
	if (fIsSavePanel) {
		BRect rect(windRect);
		rect.top = rect.bottom - 35;
		rect.left = 8;
		rect.right = rect.left + 170;
		rect.bottom = rect.top + 13;

		fTextControl = new BTextControl(rect, "text view",
			B_TRANSLATE("save text"), "", NULL,
			B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
		DisallowMetaKeys(fTextControl->TextView());
		DisallowFilenameKeys(fTextControl->TextView());
		fBackView->AddChild(fTextControl);
		fTextControl->SetDivider(0.0f);
		fTextControl->TextView()->SetMaxBytes(B_FILE_NAME_LENGTH - 1);

		fButtonText.SetTo(B_TRANSLATE("Save"));
	} else
		fButtonText.SetTo(B_TRANSLATE("Open"));

	rect = windRect;
	rect.OffsetTo(10, fDirMenuField->Frame().bottom + 10);
	rect.bottom = windRect.bottom - 60;
	rect.right -= B_V_SCROLL_BAR_WIDTH + 20;

	// re-parent the poseview to our backview
	// ToDo:
	// This is terrible, fix it up
	PoseView()->RemoveSelf();
	if (fIsSavePanel)
		fBackView->AddChild(PoseView(), fTextControl);
	else
		fBackView->AddChild(PoseView());

	PoseView()->MoveTo(rect.LeftTop());
	PoseView()->ResizeTo(rect.Width(), rect.Height());
	PoseView()->AddScrollBars();
	PoseView()->SetDragEnabled(false);
	PoseView()->SetDropEnabled(false);
	PoseView()->SetSelectionHandler(this);
	PoseView()->SetSelectionChangedHook(true);
	PoseView()->DisableSaveLocation();
	PoseView()->VScrollBar()->MoveBy(0, -1);
	PoseView()->VScrollBar()->ResizeBy(0, 1);


	AddShortcut('W', B_COMMAND_KEY, new BMessage(kCancelButton));
	AddShortcut('H', B_COMMAND_KEY, new BMessage(kSwitchToHome));
	AddShortcut('A', B_COMMAND_KEY | B_SHIFT_KEY,
		new BMessage(kShowSelectionWindow));
	AddShortcut('A', B_COMMAND_KEY, new BMessage(B_SELECT_ALL), PoseView());
	AddShortcut('S', B_COMMAND_KEY, new BMessage(kInvertSelection),
		PoseView());
	AddShortcut('Y', B_COMMAND_KEY, new BMessage(kResizeToFit), PoseView());
	AddShortcut(B_DOWN_ARROW, B_COMMAND_KEY, new BMessage(kOpenDir));
	AddShortcut(B_DOWN_ARROW, B_COMMAND_KEY | B_OPTION_KEY,
		new BMessage(kOpenDir));
	AddShortcut(B_UP_ARROW, B_COMMAND_KEY, new BMessage(kOpenParentDir));
	AddShortcut(B_UP_ARROW, B_COMMAND_KEY | B_OPTION_KEY,
		new BMessage(kOpenParentDir));

	// New code to make buttons font sensitive
	rect = windRect;
	rect.top = rect.bottom - 35;
	rect.bottom -= 10;
	rect.right -= 25;
	float default_width
		= be_plain_font->StringWidth(fButtonText.String()) + 20;
	rect.left = default_width > 75
		? rect.right - default_width : rect.right - 75;

	BButton* default_button = new BButton(rect, "default button",
		fButtonText.String(), new BMessage(kDefaultButton),
		B_FOLLOW_RIGHT + B_FOLLOW_BOTTOM);
	fBackView->AddChild(default_button);

	rect.right = rect.left -= 10;
	float cancel_width
		= be_plain_font->StringWidth(B_TRANSLATE("Cancel")) + 20;
	rect.left = cancel_width > 75
		? rect.right - cancel_width : rect.right - 75;

	BButton* cancel_button = new BButton(rect, "cancel button",
		B_TRANSLATE("Cancel"), new BMessage(kCancelButton),
		B_FOLLOW_RIGHT + B_FOLLOW_BOTTOM);
	fBackView->AddChild(cancel_button);

	if (!fIsSavePanel)
		default_button->SetEnabled(false);

	default_button->MakeDefault(true);

	RestoreState();

	PoseView()->ScrollTo(B_ORIGIN);
	PoseView()->UpdateScrollRange();
	PoseView()->ScrollTo(B_ORIGIN);

	if (fTextControl) {
		fTextControl->MakeFocus();
		fTextControl->TextView()->SelectAll();
	} else
		PoseView()->MakeFocus();

	app_info info;
	BString title;
	if (be_app->GetAppInfo(&info) == B_OK) {
		if (!gLocalizedNamePreferred
			|| BLocaleRoster::Default()->GetLocalizedFileName(
				title, info.ref, false) != B_OK)
			title = info.ref.name;
		title << ": ";
	}
	title << fButtonText;	// Open or Save

	SetTitle(title.String());

	SetSizeLimits(370, 10000, 200, 10000);
}
Esempio n. 16
0
bool
BPoseView::GetProperty(BMessage *_SCRIPTING_ONLY(specifier),
	int32 _SCRIPTING_ONLY(form), const char *_SCRIPTING_ONLY(property),
	BMessage *_SCRIPTING_ONLY(reply))
{
#if _SUPPORTS_FEATURE_SCRIPTING
//	PRINT(("GetProperty %s\n", property));
	bool handled = false;
	status_t error = B_OK;

	if (strcmp(property, kPropertyPath) == 0) {
		if (form == B_DIRECT_SPECIFIER) {
			handled = true;
			if (!TargetModel())
				error = B_NOT_A_DIRECTORY;
			else 
				reply->AddRef("result", TargetModel()->EntryRef());
		}
	} else if (strcmp(property, kPropertySelection) == 0) {
		int32 count = fSelectionList->CountItems();
		switch (form) {
			case B_DIRECT_SPECIFIER:
				// return entries of all poses in selection
				for (int32 index = 0; index < count; index++) 
					reply->AddRef("result", fSelectionList->ItemAt(index)->
						TargetModel()->EntryRef());

				handled = true;
				break;

			case kPreviousSpecifier:
			case kNextSpecifier:
				{
					// return entry and index of selected pose before or after
					// specified pose
					entry_ref ref;
					if (specifier->FindRef("data", &ref) != B_OK)
						break;
					
					int32 poseIndex;
					BPose *pose = FindPose(&ref, &poseIndex);
					
					for (;;) {
						if (form == (int32)kPreviousSpecifier)
							pose = PoseAtIndex(--poseIndex);
						else if (form == (int32)kNextSpecifier)
							pose = PoseAtIndex(++poseIndex);
						
						if (!pose) {
							error = B_ENTRY_NOT_FOUND;
							break;
						}
						
						if (pose->IsSelected()) {
							reply->AddRef("result", pose->TargetModel()->EntryRef());
							reply->AddInt32("index", IndexOfPose(pose));
							break;
						}
					}
			
					handled = true;
					break;
				}
		}
	} else if (strcmp(property, kPropertyEntry) == 0) {
		int32 count = fPoseList->CountItems();
		switch (form) {
			case B_DIRECT_SPECIFIER:
				// return all entries of all poses in PoseView
				for (int32 index = 0; index < count; index++) 
					reply->AddRef("result", PoseAtIndex(index)->TargetModel()->EntryRef());

				handled = true;
				break;
			case B_INDEX_SPECIFIER:
				{
					// return entry at index
					int32 index;
					if (specifier->FindInt32("index", &index) != B_OK)
						break;
					
					if (!PoseAtIndex(index)) {
						error = B_BAD_INDEX;
						handled = true;
						break;
					}
					reply->AddRef("result", PoseAtIndex(index)->TargetModel()->EntryRef());
	
					handled = true;
					break;
				}
			case kPreviousSpecifier:
			case kNextSpecifier:
				{
					// return entry and index of pose before or after specified pose
					entry_ref ref;
					if (specifier->FindRef("data", &ref) != B_OK)
						break;
					
					int32 tmp;
					BPose *pose = FindPose(&ref, form, &tmp);
	
					if (!pose) {
						error = B_ENTRY_NOT_FOUND;
						handled = true;
						break;
					}					
					
					reply->AddRef("result", pose->TargetModel()->EntryRef());
					reply->AddInt32("index", IndexOfPose(pose));
	
					handled = true;
					break;
				}
		}
	}
	
	if (error != B_OK)
		reply->AddInt32("error", error);

	return handled;
#else
	return false;
#endif
}
Esempio n. 17
0
void
TFilePanel::HandleSaveButton()
{
	BDirectory dir;

	if (TargetModel()->IsRoot()) {
		ShowCenteredAlert(
			B_TRANSLATE("Sorry, you can't save things at the root of "
			"your system."),
			B_TRANSLATE("Cancel"));
		return;
	}

	// check for some illegal file names
	if (strcmp(fTextControl->Text(), ".") == 0
		|| strcmp(fTextControl->Text(), "..") == 0) {
		ShowCenteredAlert(
			B_TRANSLATE("The specified name is illegal. Please choose "
			"another name."),
			B_TRANSLATE("Cancel"));
		fTextControl->TextView()->SelectAll();
		return;
	}

	if (dir.SetTo(TargetModel()->EntryRef()) != B_OK) {
		ShowCenteredAlert(
			B_TRANSLATE("There was a problem trying to save in the folder "
			"you specified. Please try another one."),
			B_TRANSLATE("Cancel"));
		return;
	}

	if (dir.Contains(fTextControl->Text())) {
		if (dir.Contains(fTextControl->Text(), B_DIRECTORY_NODE)) {
			ShowCenteredAlert(
				B_TRANSLATE("The specified name is already used as the name "
				"of a folder. Please choose another name."),
				B_TRANSLATE("Cancel"));
			fTextControl->TextView()->SelectAll();
			return;
		} else {
			// if this was invoked by a dbl click, it is an explicit
			// replacement of the file.
			BString str(B_TRANSLATE("The file \"%name\" already exists in "
				"the specified folder. Do you want to replace it?"));
			str.ReplaceFirst("%name", fTextControl->Text());

			if (ShowCenteredAlert(str.String(),	B_TRANSLATE("Cancel"),
					B_TRANSLATE("Replace"))	== 0) {
				// user canceled
				fTextControl->TextView()->SelectAll();
				return;
			}
			// user selected "Replace" - let app deal with it
		}
	}

	BMessage message(*fMessage);
	message.AddRef("directory", TargetModel()->EntryRef());
	message.AddString("name", fTextControl->Text());

	if (fClientObject)
		fClientObject->SendMessage(&fTarget, &message);
	else
		fTarget.SendMessage(&message);

	// close window if we're dealing with standard message
	if (fHideWhenDone)
		PostMessage(B_QUIT_REQUESTED);
}
bool
VirtualDirectoryPoseView::_EntryCreated(const BMessage* message)
{
	NotOwningEntryRef entryRef;
	node_ref nodeRef;

	if (message->FindInt32("device", &nodeRef.device) != B_OK
		|| message->FindInt64("node", &nodeRef.node) != B_OK
		|| message->FindInt64("directory", &entryRef.directory) != B_OK
		|| message->FindString("name", (const char**)&entryRef.name) != B_OK) {
		return true;
	}
	entryRef.device = nodeRef.device;

	// It might be one of our directories.
	BString path;
	if (message->FindString("path", &path) == B_OK
		&& fDirectoryPaths.HasString(path)) {
		// Iterate through the directory and generate an entry-created message
		// for each entry.
		BDirectory directory;
		if (directory.SetTo(&nodeRef) != B_OK)
			return true;

		BPrivate::Storage::LongDirEntry entry;
		while (directory.GetNextDirents(&entry, sizeof(entry), 1) == 1) {
			if (strcmp(entry.d_name, ".") != 0
				&& strcmp(entry.d_name, "..") != 0) {
				_DispatchEntryCreatedOrRemovedMessage(B_ENTRY_CREATED,
					node_ref(entry.d_dev, entry.d_ino),
					NotOwningEntryRef(entry.d_pdev, entry.d_pino,
						entry.d_name),
					NULL, false);
			}
		}
		return true;
	}

	// See, if this entry actually becomes visible. If not, we can simply ignore
	// it.
	struct stat st;
	entry_ref visibleEntryRef;
	if (!_GetEntry(entryRef.name, visibleEntryRef, &st)
		|| visibleEntryRef != entryRef) {
		return true;
	}

	// If it is a directory, translate it.
	VirtualDirectoryManager* manager = VirtualDirectoryManager::Instance();
	AutoLocker<VirtualDirectoryManager> managerLocker(manager);

	bool entryTranslated = S_ISDIR(st.st_mode);
	if (entryTranslated) {
		if (manager == NULL)
			return true;

		if (manager->TranslateDirectoryEntry(*TargetModel()->NodeRef(),
				entryRef, nodeRef) != B_OK) {
			return true;
		}
	}

	// The entry might replace another entry. If it does, we'll fake a removed
	// message for the old one first.
	BPose* pose = fPoseList->FindPoseByFileName(entryRef.name);
	if (pose != NULL) {
		if (nodeRef == *pose->TargetModel()->NodeRef()) {
			// apparently not really a new entry -- can happen for
			// subdirectories
			return true;
		}

		// It may be a directory, so tell the manager.
		if (manager != NULL)
			manager->DirectoryRemoved(*pose->TargetModel()->NodeRef());

		managerLocker.Unlock();

		BMessage removedMessage(B_NODE_MONITOR);
		_DispatchEntryCreatedOrRemovedMessage(B_ENTRY_REMOVED,
			*pose->TargetModel()->NodeRef(), *pose->TargetModel()->EntryRef());
	} else
		managerLocker.Unlock();

	return entryTranslated
		? (_DispatchEntryCreatedOrRemovedMessage(B_ENTRY_CREATED, nodeRef,
			entryRef), true)
		: _inherited::FSNotification(message);
}
Esempio n. 19
0
void
TFilePanel::MessageReceived(BMessage* message)
{
	entry_ref ref;

	switch (message->what) {
		case B_REFS_RECEIVED:
			// item was double clicked in file panel (PoseView)
			if (message->FindRef("refs", &ref) == B_OK) {
				BEntry entry(&ref, true);
				if (entry.InitCheck() == B_OK) {
					// Double-click on dir or link-to-dir ALWAYS opens the
					// dir. If more than one dir is selected, the first is
					// entered.
					if (entry.IsDirectory()) {
						entry.GetRef(&ref);
						bool isDesktop = SwitchDirToDesktopIfNeeded(ref);

						PoseView()->SetIsDesktop(isDesktop);
						entry.SetTo(&ref);
						PoseView()->SwitchDir(&ref);
						SwitchDirMenuTo(&ref);
					} else {
						// Otherwise, we have a file or a link to a file.
						// AdjustButton has already tested the flavor;
						// all we have to do is see if the button is enabled.
						BButton* button = dynamic_cast<BButton*>(
							FindView("default button"));
						if (button == NULL)
							break;

						if (IsSavePanel()) {
							int32 count = 0;
							type_code type;
							message->GetInfo("refs", &type, &count);

							// Don't allow saves of multiple files
							if (count > 1) {
								ShowCenteredAlert(
									B_TRANSLATE(
										"Sorry, saving more than one "
										"item is not allowed."),
									B_TRANSLATE("Cancel"));
							} else {
								// if we are a savepanel, set up the
								// filepanel correctly then pass control
								// so we follow the same path as if the user
								// clicked the save button

								// set the 'name' fld to the current ref's
								// name notify the panel that the default
								// button should be enabled
								SetSaveText(ref.name);
								SelectionChanged();

								HandleSaveButton();
							}
							break;
						}

					  	// send handler a message and close
						BMessage openMessage(*fMessage);
						for (int32 index = 0; ; index++) {
					  		if (message->FindRef("refs", index, &ref) != B_OK)
								break;
							openMessage.AddRef("refs", &ref);
					  	}
						OpenSelectionCommon(&openMessage);
					}
				}
			}
			break;

		case kSwitchDirectory:
		{
			entry_ref ref;
			// this comes from dir menu or nav menu, so switch directories
			if (message->FindRef("refs", &ref) == B_OK) {
				BEntry entry(&ref, true);
				if (entry.GetRef(&ref) == B_OK)
					SetTo(&ref);
			}
			break;
		}

		case kSwitchToHome:
		{
			BPath homePath;
			entry_ref ref;
			if (find_directory(B_USER_DIRECTORY, &homePath) != B_OK
				|| get_ref_for_path(homePath.Path(), &ref) != B_OK) {
				break;
			}

			SetTo(&ref);
			break;
		}

		case kAddCurrentDir:
		{
			BPath path;
			if (find_directory(B_USER_SETTINGS_DIRECTORY, &path, true)
					!= B_OK) {
				break;
			}

			path.Append(kGoDirectory);
			BDirectory goDirectory(path.Path());

			if (goDirectory.InitCheck() == B_OK) {
				BEntry entry(TargetModel()->EntryRef());
				entry.GetPath(&path);

				BSymLink link;
				goDirectory.CreateSymLink(TargetModel()->Name(), path.Path(),
					&link);
			}
			break;
		}

		case kEditFavorites:
		{
			BPath path;
			if (find_directory (B_USER_SETTINGS_DIRECTORY, &path, true)
					!= B_OK) {
				break;
			}

			path.Append(kGoDirectory);
			BMessenger msgr(kTrackerSignature);
			if (msgr.IsValid()) {
				BMessage message(B_REFS_RECEIVED);
				entry_ref ref;
				if (get_ref_for_path(path.Path(), &ref) == B_OK) {
					message.AddRef("refs", &ref);
					msgr.SendMessage(&message);
				}
			}
			break;
		}

		case kCancelButton:
			PostMessage(B_QUIT_REQUESTED);
			break;

		case kResizeToFit:
			ResizeToFit();
			break;

		case kOpenDir:
			OpenDirectory();
			break;

		case kOpenParentDir:
			OpenParent();
			break;

		case kDefaultButton:
			if (fIsSavePanel) {
				if (PoseView()->IsFocus()
					&& PoseView()->SelectionList()->CountItems() == 1) {
					Model* model = (PoseView()->SelectionList()->
						FirstItem())->TargetModel();
					if (model->ResolveIfLink()->IsDirectory()) {
						PoseView()->CommitActivePose();
						PoseView()->OpenSelection();
						break;
					}
				}

				HandleSaveButton();
			} else
				HandleOpenButton();
			break;

		case B_OBSERVER_NOTICE_CHANGE:
		{
			int32 observerWhat;
			if (message->FindInt32("be:observe_change_what", &observerWhat)
					== B_OK) {
				switch (observerWhat) {
					case kDesktopFilePanelRootChanged:
					{
						bool desktopIsRoot = true;
						if (message->FindBool("DesktopFilePanelRoot",
								&desktopIsRoot) == B_OK) {
							TrackerSettings().
								SetDesktopFilePanelRoot(desktopIsRoot);
						}
						SetTo(TargetModel()->EntryRef());
						break;
					}
				}
			}
			break;
		}

		default:
			_inherited::MessageReceived(message);
			break;
	}
}
bool
VirtualDirectoryPoseView::_EntryRemoved(const BMessage* message)
{
	NotOwningEntryRef entryRef;
	node_ref nodeRef;

	if (message->FindInt32("device", &nodeRef.device) != B_OK
		|| message->FindInt64("node", &nodeRef.node) != B_OK
		|| message->FindInt64("directory", &entryRef.directory)
			!= B_OK
		|| message->FindString("name", (const char**)&entryRef.name) != B_OK) {
		return true;
	}
	entryRef.device = nodeRef.device;

	// It might be our definition file.
	if (nodeRef == *TargetModel()->NodeRef())
		return _inherited::FSNotification(message);

	// It might be one of our directories.
	BString path;
	if (message->FindString("path", &path) == B_OK
		&& fDirectoryPaths.HasString(path)) {
		// Find all poses that stem from that directory and generate an
		// entry-removed message for each.
		PoseList poses;
		for (int32 i = 0; BPose* pose = fPoseList->ItemAt(i); i++) {
			NotOwningEntryRef poseEntryRef = *pose->TargetModel()->EntryRef();
			if (poseEntryRef.DirectoryNodeRef() == nodeRef)
				poses.AddItem(pose);
		}

		for (int32 i = 0; BPose* pose = poses.ItemAt(i); i++) {
			_DispatchEntryCreatedOrRemovedMessage(B_ENTRY_REMOVED,
				*pose->TargetModel()->NodeRef(),
				*pose->TargetModel()->EntryRef(), NULL, false);
		}

		return true;
	}

	// If it is a directory, translate it.
	entry_ref* actualEntryRef = &entryRef;
	node_ref* actualNodeRef = &nodeRef;
	entry_ref definitionEntryRef;
	node_ref definitionNodeRef;

	VirtualDirectoryManager* manager = VirtualDirectoryManager::Instance();
	AutoLocker<VirtualDirectoryManager> managerLocker(manager);

	if (manager != NULL
		&& manager->GetSubDirectoryDefinitionFile(*TargetModel()->NodeRef(),
			entryRef.name, definitionEntryRef, definitionNodeRef)) {
		actualEntryRef = &definitionEntryRef;
		actualNodeRef = &definitionNodeRef;
	}

	// Check the pose. It might have been an entry that wasn't visible anyway.
	// In that case we can just ignore the notification.
	BPose* pose = fPoseList->FindPoseByFileName(actualEntryRef->name);
	if (pose == NULL || *actualNodeRef != *pose->TargetModel()->NodeRef())
		return true;

	// See, if another entry becomes visible, now.
	struct stat st;
	entry_ref visibleEntryRef;
	node_ref visibleNodeRef;
	if (_GetEntry(actualEntryRef->name, visibleEntryRef, &st)) {
		// If the new entry is a directory, translate it.
		visibleNodeRef = node_ref(st.st_dev, st.st_ino);
		if (S_ISDIR(st.st_mode)) {
			if (manager == NULL || manager->TranslateDirectoryEntry(
					*TargetModel()->NodeRef(), visibleEntryRef, visibleNodeRef)
					!= B_OK) {
				return true;
			}

			// Effectively nothing changes, when the removed entry was a
			// directory as well.
			if (visibleNodeRef == *actualNodeRef)
				return true;
		}
	}

	if (actualEntryRef == &entryRef) {
		managerLocker.Unlock();
		if (_inherited::FSNotification(message))
			pendingNodeMonitorCache.Add(message);
	} else {
		// tell the manager that the directory has been removed
		manager->DirectoryRemoved(*actualNodeRef);
		managerLocker.Unlock();

		_DispatchEntryCreatedOrRemovedMessage(B_ENTRY_REMOVED, *actualNodeRef,
			*actualEntryRef);
	}

	_DispatchEntryCreatedOrRemovedMessage(B_ENTRY_CREATED, visibleNodeRef,
		visibleEntryRef);

	return true;
}