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); }
void BNavigator::GoTo() { BString pathname = fLocation->Text(); if (pathname.Compare("") == 0) pathname = "/"; BEntry entry; entry_ref ref; if (entry.SetTo(pathname.String()) == B_OK && !FSIsDeskDir(&entry) && entry.GetRef(&ref) == B_OK) { BMessage message(kSwitchDirectory); message.AddRef("refs", &ref); message.AddInt32("action", kActionLocation); Window()->PostMessage(&message); } else { BPath path; if (Window() && Window()->TargetModel()) { Window()->TargetModel()->GetPath(&path); fLocation->SetText(path.Path()); } } }
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; }
void BNavigator::GoUp(bool option) { BEntry entry; if (entry.SetTo(fPath.Path()) == B_OK) { BEntry parentEntry; if (entry.GetParent(&parentEntry) == B_OK && !FSIsDeskDir(&parentEntry)) SendNavigationMessage(kActionUp, &parentEntry, option); } }
void BNavigator::UpdateLocation(const Model *newmodel, int32 action) { if (newmodel) newmodel->GetPath(&fPath); // Modify history according to commands switch (action) { case kActionBackward: fForwHistory.AddItem(fBackHistory.RemoveItemAt(fBackHistory.CountItems()-1)); break; case kActionForward: fBackHistory.AddItem(fForwHistory.RemoveItemAt(fForwHistory.CountItems()-1)); break; case kActionUpdatePath: break; default: fForwHistory.MakeEmpty(); fBackHistory.AddItem(new BPath(fPath)); for (;fBackHistory.CountItems()>kMaxHistory;) fBackHistory.RemoveItem(fBackHistory.FirstItem(), true); break; } // Enable Up button when there is any parent BEntry entry; if (entry.SetTo(fPath.Path()) == B_OK) { BEntry parentEntry; fUp->SetEnabled(entry.GetParent(&parentEntry) == B_OK && !FSIsDeskDir(&parentEntry)); } // Enable history buttons if history contains something fForw->SetEnabled(fForwHistory.CountItems() > 0); fBack->SetEnabled(fBackHistory.CountItems() > 1); // Avoid loss of selection and cursor position if (action != kActionLocation) fLocation->SetText(fPath.Path()); }
void BDirMenu::AddItemToDirMenu(const BEntry *entry, BWindow *originatingWindow, bool atEnd, bool addShortcuts) { Model model(entry); if (model.InitCheck() != B_OK) return; BMessage *message = new BMessage(fCommand); message->AddRef(fEntryName.String(), model.EntryRef()); // add reference to the container windows model so that we can // close the window if BContainerWindow *window = originatingWindow ? dynamic_cast<BContainerWindow *>(originatingWindow) : 0; if (window) message->AddData("nodeRefsToClose", B_RAW_TYPE, window->TargetModel()->NodeRef(), sizeof (node_ref)); ModelMenuItem *item = new ModelMenuItem(&model, model.Name(), message); if (addShortcuts) { if (FSIsDeskDir(entry)) item->SetShortcut('D', B_COMMAND_KEY); else if (FSIsHomeDir(entry)) item->SetShortcut('H', B_COMMAND_KEY); } if (atEnd) AddItem(item); else AddItem(item, 0); if (fMenuBar) { ModelMenuItem *menu = dynamic_cast<ModelMenuItem *>(fMenuBar->ItemAt(0)); if (menu) { ThrowOnError(menu->SetEntry(entry)); item->SetMarked(true); } } }
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; } }
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; }