Пример #1
0
bool
BNavMenu::StartBuildingItemList()
{
	BEntry entry;

	if (fNavDir.device < 0 || entry.SetTo(&fNavDir) != B_OK
		|| !entry.Exists()) 
		return false;

	fItemList = new BObjectList<BMenuItem>(50);

	fIteratingDesktop = false;
	
	BDirectory parent;
	status_t status = entry.GetParent(&parent);

	// if ref is the root item then build list of volume root dirs
	fFlags = uint8((fFlags & ~kVolumesOnly) | (status == B_ENTRY_NOT_FOUND ? kVolumesOnly : 0));
	if (fFlags & kVolumesOnly)
		return true;
		
	Model startModel(&entry, true);
	if (startModel.InitCheck() != B_OK || !startModel.IsContainer()) 
		return false;

	if (startModel.IsQuery()) 
		fContainer = new QueryEntryListCollection(&startModel);
	else if (FSIsDeskDir(&entry)) {
		fIteratingDesktop = true;
		fContainer = DesktopPoseView::InitDesktopDirentIterator(0, startModel.EntryRef());
		AddRootItemsIfNeeded();
	} else if (FSIsTrashDir(&entry)) {
		// the trash window needs to display a union of all the
		// trash folders from all the mounted volumes
		BVolumeRoster volRoster;
		volRoster.Rewind();
		BVolume volume;
		fContainer = new EntryIteratorList();
		
		while (volRoster.GetNextVolume(&volume) == B_OK) {
			if (!volume.IsPersistent())
				continue;
			
			BDirectory trashDir;
			
			if (FSGetTrashDir(&trashDir, volume.Device()) == B_OK)
				dynamic_cast<EntryIteratorList *>(fContainer)->
					AddItem(new DirectoryEntryList(trashDir));
		}
	} else
		fContainer = new DirectoryEntryList(*dynamic_cast<BDirectory *>
			(startModel.Node()));
	
	if (fContainer == NULL || fContainer->InitCheck() != B_OK)
		return false;

	fContainer->Rewind();

	return true;
}
Пример #2
0
void
Model::FinishSettingUpType()
{
    char mimeString[B_MIME_TYPE_LENGTH];
    BEntry entry;

    // while we are reading the node, do a little
    // snooping to see if it even makes sense to look for a node-based
    // icon
    // This serves as a hint to the icon cache, allowing it to not hit the
    // disk again for models that do not have an icon defined by the node
    if (IsNodeOpen()
            && fBaseType != kLinkNode
            && !CheckNodeIconHintPrivate(fNode, dynamic_cast<TTracker *>(be_app) == NULL)
            && !HasVectorIconHint(fNode)) {
        // when checking for the node icon hint, if we are libtracker, only check
        // for small icons - checking for the large icons is a little more
        // work for the filesystem and this will speed up the test.
        // This makes node icons only work if there is a small and a large node
        // icon on a file - for libtracker that is not a problem though
        fIconFrom = kUnknownNotFromNode;
    }

    if (fBaseType != kDirectoryNode
            && fBaseType != kVolumeNode
            && fBaseType != kLinkNode
            && IsNodeOpen()) {
        BNodeInfo info(fNode);

        // check if a specific mime type is set
        if (info.GetType(mimeString) == B_OK) {
            // node has a specific mime type
            fMimeType = mimeString;
            if (strcmp(mimeString, B_QUERY_MIMETYPE) == 0)
                fBaseType = kQueryNode;
            else if (strcmp(mimeString, B_QUERY_TEMPLATE_MIMETYPE) == 0)
                fBaseType = kQueryTemplateNode;

            if (info.GetPreferredApp(mimeString) == B_OK) {
                if (fPreferredAppName)
                    DeletePreferredAppVolumeNameLinkTo();

                if (mimeString[0])
                    fPreferredAppName = strdup(mimeString);
            }
        }
    }

    switch (fBaseType) {
    case kDirectoryNode:
        entry.SetTo(&fEntryRef);
        if (entry.InitCheck() == B_OK) {
            if (FSIsTrashDir(&entry))
                fBaseType = kTrashNode;
            else if (FSIsDeskDir(&entry))
                fBaseType = kDesktopNode;
        }

        fMimeType = B_DIR_MIMETYPE;	// should use a shared string here
        if (IsNodeOpen()) {
            BNodeInfo info(fNode);
            if (info.GetType(mimeString) == B_OK)
                fMimeType = mimeString;

            if (fIconFrom == kUnknownNotFromNode
                    && WellKnowEntryList::Match(NodeRef()) > (directory_which)-1)
                // one of home, beos, system, boot, etc.
                fIconFrom = kTrackerSupplied;
        }
        break;

    case kVolumeNode:
    {
        if (NodeRef()->node == fEntryRef.directory
                && NodeRef()->device == fEntryRef.device) {
            // promote from volume to file system root
            fBaseType = kRootNode;
            fMimeType = B_ROOT_MIMETYPE;
            break;
        }

        // volumes have to have a B_VOLUME_MIMETYPE type
        fMimeType = B_VOLUME_MIMETYPE;
        if (fIconFrom == kUnknownNotFromNode) {
            if (WellKnowEntryList::Match(NodeRef()) > (directory_which)-1)
                fIconFrom = kTrackerSupplied;
            else
                fIconFrom = kVolume;
        }

        char name[B_FILE_NAME_LENGTH];
        BVolume	volume(NodeRef()->device);
        if (volume.InitCheck() == B_OK && volume.GetName(name) == B_OK) {
            if (fVolumeName)
                DeletePreferredAppVolumeNameLinkTo();

            fVolumeName = strdup(name);
        }
#if DEBUG
        else
            PRINT(("get volume name failed for %s\n", fEntryRef.name));
#endif
        break;
    }

    case kLinkNode:
        fMimeType = B_LINK_MIMETYPE;	// should use a shared string here
        break;

    case kExecutableNode:
        if (IsNodeOpen()) {
            char signature[B_MIME_TYPE_LENGTH];
            if (GetAppSignatureFromAttr(dynamic_cast<BFile *>(fNode), signature)
                    == B_OK) {

                if (fPreferredAppName)
                    DeletePreferredAppVolumeNameLinkTo();

                if (signature[0])
                    fPreferredAppName = strdup(signature);
            }
        }
        if (!fMimeType.Length())
            fMimeType = B_APP_MIME_TYPE;	// should use a shared string here
        break;

    default:
        if (!fMimeType.Length())
            fMimeType = B_FILE_MIMETYPE;
        break;
    }
}
Пример #3
0
bool
FSClipboardPaste(Model *model, uint32 linksMode)
{
	if (!FSClipboardHasRefs())
		return false;

	BMessenger tracker(kTrackerSignature);

	node_ref *destNodeRef = (node_ref *)model->NodeRef();

	// these will be passed to the asynchronous copy/move process
	BObjectList<entry_ref> *moveList = new BObjectList<entry_ref>(0, true);
	BObjectList<entry_ref> *copyList = new BObjectList<entry_ref>(0, true);

	if ((be_clipboard->Lock())) {
		BMessage *clip = be_clipboard->Data();
		if (clip != NULL) {
			char modeName[64];
			uint32 moveMode = 0;

			BMessage *updateMessage = NULL;
			node_ref updateNodeRef;
			updateNodeRef.device = -1;

			char *refName;
			type_code type;
			int32 count;
			for (int32 index = 0; clip->GetInfo(B_REF_TYPE, index,
#ifdef B_BEOS_VERSION_DANO
				(const char **)
#endif
				&refName, &type, &count) == B_OK; index++) {
				entry_ref ref;
				if (clip->FindRef(refName, &ref) != B_OK)
					continue;

				// If the entry_ref's directory has changed, send previous notification
				// (if any), and start new one for the new directory
				if (updateNodeRef.device != ref.device
					|| updateNodeRef.node != ref.directory) {
					if (updateMessage != NULL) {
						tracker.SendMessage(updateMessage);
						delete updateMessage;
					}

					updateNodeRef.device = ref.device;
					updateNodeRef.node = ref.directory;

					updateMessage = new BMessage(kFSClipboardChanges);
					updateMessage->AddInt32("device", updateNodeRef.device);
					updateMessage->AddInt64("directory", updateNodeRef.node);					
				}

				// we need this data later on
				MakeModeNameFromRefName(modeName, refName);
				if (!linksMode && clip->FindInt32(modeName, (int32 *)&moveMode) != B_OK)
					continue;

				BEntry entry(&ref);

				uint32 newMoveMode = 0;
				bool sameDirectory = destNodeRef->device == ref.device && destNodeRef->node == ref.directory;
				
				if (!entry.Exists()) {
					// The entry doesn't exist anymore, so we'll remove
					// that entry from the clipboard as well
					clip->RemoveName(refName);
					clip->RemoveName(modeName);

					newMoveMode = kDelete;
				} else {
					// the entry does exist, so lets see what we will
					// do with it
					if (!sameDirectory) {
						if (linksMode || moveMode == kMoveSelectionTo) {
							// the linksMode uses the moveList as well
							moveList->AddItem(new entry_ref(ref));
						} else if (moveMode == kCopySelectionTo)
							copyList->AddItem(new entry_ref(ref));
					}

					// if the entry should have been removed from its directory,
					// we want to copy that entry next time, no matter if the
					// items don't have to be moved at all (source == target)
					if (moveMode == kMoveSelectionTo)
						newMoveMode = kCopySelectionTo;
				}

				// add the change to the update message (if necessary)
				if (newMoveMode) {
					clip->ReplaceInt32(modeName, kCopySelectionTo);

					TClipboardNodeRef clipNode;
					MakeNodeFromName(&clipNode.node, modeName);
					clipNode.moveMode = kDelete;
					updateMessage->AddData("tcnode", T_CLIPBOARD_NODE, &clipNode,
						sizeof(TClipboardNodeRef), true);
				}
			}
			be_clipboard->Commit();

			// send notification for the last directory
			if (updateMessage != NULL) {
				tracker.SendMessage(updateMessage);
				delete updateMessage;
			}
		}
		be_clipboard->Unlock();
	}

	bool okToMove = true;

	// can't copy/paste to root('/') directory
	if (model->IsRoot()) {
		(new BAlert("", kNoCopyToRootStr, "Cancel", NULL, NULL,
			B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go();
		okToMove = false;			
	}

	BEntry entry;
	model->GetEntry(&entry);

	// can't copy items into the trash
	if (copyList->CountItems() > 0 && FSIsTrashDir(&entry)) {
		(new BAlert("", kNoCopyToTrashStr, "Cancel", NULL, NULL,
			B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go();
		okToMove = false;
	}

	if (!okToMove) {
		// there was some problem with our target, so we bail out here
		delete moveList;
		delete copyList;
		return false;
	}

	// asynchronous calls take over ownership of the objects passed to it
	if (moveList->CountItems() > 0)
		FSMoveToFolder(moveList, new BEntry(entry), linksMode ? linksMode : kMoveSelectionTo);
	else
		delete moveList;

	if (copyList->CountItems() > 0)
		FSMoveToFolder(copyList, new BEntry(entry), kCopySelectionTo);
	else
		delete copyList;

	return true;
}
Пример #4
0
uint32
FSClipboardAddPoses(const node_ref *directory, PoseList *list, uint32 moveMode,
	bool clearClipboard)
{
	uint32 refsAdded = 0;
	int32 listCount = list->CountItems();

	if (listCount == 0 || !be_clipboard->Lock())
		return 0;

	// update message to be send to all listeners
	BMessage updateMessage(kFSClipboardChanges);
	updateMessage.AddInt32("device", directory->device);
	updateMessage.AddInt64("directory", directory->node);
	updateMessage.AddBool("clearClipboard", clearClipboard);

	TClipboardNodeRef clipNode;
	clipNode.moveMode = moveMode;

	if (clearClipboard)
		be_clipboard->Clear();

	BMessage *clip = be_clipboard->Data();
	if (clip != NULL) {
		for (int32 index = 0; index < listCount; index++) {
			char refName[64], modeName[64];
			BPose *pose = (BPose *)list->ItemAt(index);
			Model *model = pose->TargetModel();
			const node_ref *node = model->NodeRef();

			BEntry entry;
			model->GetEntry(&entry);
			if (model->IsVolume()
				|| model->IsRoot()
				|| FSIsTrashDir(&entry)
				|| FSIsDeskDir(&entry))
				continue;

			MakeRefName(refName, node);
			MakeModeNameFromRefName(modeName, refName);

			if (clearClipboard) {
				if (clip->AddInt32(modeName, (int32)moveMode) == B_OK)
					if (clip->AddRef(refName, model->EntryRef()) == B_OK) {
						pose->SetClipboardMode(moveMode);

						clipNode.node = *node;
						updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, &clipNode,
							sizeof(TClipboardNodeRef), true, listCount);

						refsAdded++;
					} else
						clip->RemoveName(modeName);
			} else {
				if (clip->ReplaceInt32(modeName, (int32)moveMode) == B_OK) {
					// replace old mode if entry already exists in clipboard
					if (clip->ReplaceRef(refName, model->EntryRef()) == B_OK) {
						pose->SetClipboardMode(moveMode);

						clipNode.node = *node;
						updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, &clipNode,
							sizeof(TClipboardNodeRef), true, listCount);

						refsAdded++;
					} else {
						clip->RemoveName(modeName);
						
						clipNode.node = *node;
						clipNode.moveMode = kDelete;	// note removing node
						updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, &clipNode,
							sizeof(TClipboardNodeRef), true, listCount);
						clipNode.moveMode = moveMode; // set it back to current value
					}
				} else {
					// add it if it doesn't exist
					if (clip->AddRef(refName, model->EntryRef()) == B_OK
						&& clip->AddInt32(modeName, (int32)moveMode) == B_OK) {
						pose->SetClipboardMode(moveMode);
						
						clipNode.node = *node;
						updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, &clipNode,
							sizeof(TClipboardNodeRef), true, listCount);

						refsAdded++;
					} else {
						clip->RemoveName(modeName);
						clip->RemoveName(refName);
						// here notifying delete isn't needed as node didn't
						// exist in clipboard
					}
				}
			}
		}
		be_clipboard->Commit();
	}	
	be_clipboard->Unlock();

	BMessenger(kTrackerSignature).SendMessage(&updateMessage);
		// Tracker will notify all listeners

	return refsAdded;
}