PoseList* PoseList::FindAllPoses(const node_ref* node) const { int32 count = CountItems(); PoseList *result = new PoseList(5, false); for (int32 index = 0; index < count; index++) { BPose *pose = ItemAt(index); Model *model = pose->TargetModel(); if (*model->NodeRef() == *node) { result->AddItem(pose, 0); continue; } if (!model->IsSymLink()) continue; model = model->LinkTo(); if (model != NULL && *model->NodeRef() == *node) { result->AddItem(pose); continue; } if (model == NULL) { Model model(pose->TargetModel()->EntryRef(), true); if (*model.NodeRef() == *node) result->AddItem(pose); } } return result; }
BPose* PoseList::DeepFindPose(const node_ref* node, int32* resultingIndex) const { int32 count = CountItems(); for (int32 index = 0; index < count; index++) { BPose* pose = ItemAt(index); Model* model = pose->TargetModel(); if (*model->NodeRef() == *node) { if (resultingIndex != NULL) *resultingIndex = index; return pose; } // if model is a symlink, try matching node with the target // of the link if (model->IsSymLink()) { model = model->LinkTo(); if (model != NULL && *model->NodeRef() == *node) { if (resultingIndex != NULL) *resultingIndex = index; return pose; } } } return NULL; }
BPose* PoseList::FindPose(const entry_ref* entry, int32* resultingIndex) const { int32 count = CountItems(); for (int32 index = 0; index < count; index++) { BPose* pose = ItemAt(index); ASSERT(pose->TargetModel()); if (*pose->TargetModel()->EntryRef() == *entry) { if (resultingIndex != NULL) *resultingIndex = index; return pose; } } return NULL; }
BPose* PoseList::FindPose(const node_ref* node, int32* resultingIndex) const { int32 count = CountItems(); for (int32 index = 0; index < count; index++) { BPose* pose = ItemAt(index); ASSERT(pose->TargetModel()); if (*pose->TargetModel()->NodeRef() == *node) { if (resultingIndex) *resultingIndex = index; return pose; } } return NULL; }
void OpenWithContainerWindow::MakeDefaultAndOpen() { int32 count = PoseView()->SelectionList()->CountItems(); ASSERT(count == 1); if (count == 0) return; BPose* selectedAppPose = PoseView()->SelectionList()->FirstItem(); ASSERT(selectedAppPose != NULL); if (selectedAppPose == NULL) return; // collect all the types of all the opened documents into a list BObjectList<BString> openedFileTypes(10, true); EachEntryRef(EntryList(), AddOneUniqueDocumentType, &openedFileTypes, 100); // set the default application to be the selected pose for all the // mime types in the list openedFileTypes.EachElement(SetDefaultAppForOneType, (void*)selectedAppPose->TargetModel()->EntryRef()); // done setting the default application, now launch the app with the // documents OpenWithSelection(); }
BPose* PoseList::FindPoseByFileName(const char* name, int32* _index) const { int32 count = CountItems(); for (int32 index = 0; index < count; index++) { BPose* pose = ItemAt(index); ASSERT(pose->TargetModel()); if (strcmp(pose->TargetModel()->EntryRef()->name, name) == 0) { if (_index) *_index = index; return pose; } } return NULL; }
bool BPoseView::ExecuteProperty(BMessage *_SCRIPTING_ONLY(specifier), int32 _SCRIPTING_ONLY(form), const char *_SCRIPTING_ONLY(property), BMessage *_SCRIPTING_ONLY(reply)) { #if _SUPPORTS_FEATURE_SCRIPTING status_t error = B_OK; bool handled = false; if (strcmp(property, kPropertyEntry) == 0) { BMessage launchMessage(B_REFS_RECEIVED); if (form == (int32)B_ENTRY_SPECIFIER) { // move all poses specified by entry_ref to Trash entry_ref ref; for (int32 index = 0; specifier->FindRef("refs", index, &ref) == B_OK; index++) launchMessage.AddRef("refs", &ref); } else if (form == (int32)B_INDEX_SPECIFIER) { // move all poses specified by index to Trash int32 specifyingIndex; for (int32 index = 0; specifier->FindInt32("index", index, &specifyingIndex) == B_OK; index++) { BPose *pose = PoseAtIndex(specifyingIndex); if (!pose) { error = B_ENTRY_NOT_FOUND; break; } launchMessage.AddRef("refs", pose->TargetModel()->EntryRef()); } } else return false; if (error == B_OK) { // add a messenger to the launch message that will be used to // dispatch scripting calls from apps to the PoseView launchMessage.AddMessenger("TrackerViewToken", BMessenger(this, 0, 0)); if (fSelectionHandler) fSelectionHandler->PostMessage(&launchMessage); } handled = true; } if (error != B_OK) reply->AddInt32("error", error); return handled; #else return false; #endif }
status_t TFilePanel::GetNextEntryRef(entry_ref* ref) { if (!ref) return B_ERROR; BPose* pose = fPoseView->SelectionList()->ItemAt(fSelectionIterator++); if (!pose) return B_ERROR; *ref = *pose->TargetModel()->EntryRef(); return B_OK; }
void BQueryPoseView::AddPosesCompleted() { ASSERT(Window()->IsLocked()); PoseList* oldPoseList = fQueryListContainer->OldPoseList(); if (oldPoseList) { int32 count = oldPoseList->CountItems(); for (int32 index = count - 1; index >= 0; index--) { BPose* pose = oldPoseList->ItemAt(index); DeletePose(pose->TargetModel()->NodeRef()); } fQueryListContainer->ClearOldPoseList(); } _inherited::AddPosesCompleted(); }
uint32 FSClipboardRemovePoses(const node_ref *directory, PoseList *list) { if (!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", false); TClipboardNodeRef clipNode; clipNode.moveMode = kDelete; uint32 refsRemoved = 0; BMessage *clip = be_clipboard->Data(); if (clip != NULL) { int32 listCount = list->CountItems(); for (int32 index = 0; index < listCount; index++) { char refName[64], modeName[64]; BPose *pose = (BPose *)list->ItemAt(index); clipNode.node = *pose->TargetModel()->NodeRef(); MakeRefName(refName, &clipNode.node); MakeModeName(modeName); if (clip->RemoveName(refName) == B_OK && clip->RemoveName(modeName)) { updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, &clipNode, sizeof(TClipboardNodeRef), true, listCount); refsRemoved++; } } be_clipboard->Commit(); } be_clipboard->Unlock(); BMessenger(kTrackerSignature).SendMessage(&updateMessage); // Tracker will notify all listeners return refsRemoved; }
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; }
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); }
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; }
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 }
bool BPoseView::DeleteProperty(BMessage *_SCRIPTING_ONLY(specifier), int32 _SCRIPTING_ONLY(form), const char *_SCRIPTING_ONLY(property), BMessage *_SCRIPTING_ONLY(reply)) { #if _SUPPORTS_FEATURE_SCRIPTING status_t error = B_OK; bool handled = false; if (strcmp(property, kPropertySelection) == 0) { // deleting on a selection is handled as removing a part of the selection // not to be confused with deleting a selected item if (form == (int32)B_ENTRY_SPECIFIER) { entry_ref ref; // select poses specified by entries for (int32 index = 0; specifier->FindRef("refs", index, &ref) == B_OK; index++) { int32 poseIndex; BPose *pose = FindPose(&ref, form, &poseIndex); if (!pose) { error = B_ENTRY_NOT_FOUND; break; } RemovePoseFromSelection(pose); } handled = true; } else if (form == B_INDEX_SPECIFIER) { // move all poses specified by index to Trash int32 specifyingIndex; for (int32 index = 0; specifier->FindInt32("index", index, &specifyingIndex) == B_OK; index++) { BPose *pose = PoseAtIndex(specifyingIndex); if (!pose) { error = B_BAD_INDEX; break; } RemovePoseFromSelection(pose); } handled = true; } else return false; } else if (strcmp(property, kPropertyEntry) == 0) { // deleting entries is handled by moving entries to trash // build a list of entries, specified by the specifier BObjectList<entry_ref> *entryList = new BObjectList<entry_ref>(); // list will be deleted for us by the trashing thread if (form == (int32)B_ENTRY_SPECIFIER) { // move all poses specified by entry_ref to Trash entry_ref ref; for (int32 index = 0; specifier->FindRef("refs", index, &ref) == B_OK; index++) entryList->AddItem(new entry_ref(ref)); } else if (form == (int32)B_INDEX_SPECIFIER) { // move all poses specified by index to Trash int32 specifyingIndex; for (int32 index = 0; specifier->FindInt32("index", index, &specifyingIndex) == B_OK; index++) { BPose *pose = PoseAtIndex(specifyingIndex); if (!pose) { error = B_BAD_INDEX; break; } entryList->AddItem(new entry_ref(*pose->TargetModel()->EntryRef())); } } else return false; if (error == B_OK) { TrackerSettings settings; if (!settings.DontMoveFilesToTrash()) { // move the list we build into trash, don't make the trashing task // select the next item MoveListToTrash(entryList, false, false); } else Delete(entryList, false, settings.AskBeforeDeleteFile()); } handled = true; } if (error != B_OK) reply->AddInt32("error", error); return handled; #else return false; #endif }
/*! \brief Tracker add-on entry */ extern "C" void process_refs(entry_ref dir, BMessage* refs, void* /*reserved*/) { status_t status; BAlert *alert; BMessenger msgr; BPoseView *view = NULL; BMessage poseViewBackup; BMessage poseViewColumnBackup; uint32 poseViewModeBackup; BString windowTitleBackup; refs->PrintToStream(); status = refs->FindMessenger("TrackerViewToken", &msgr); if (status < B_OK) { Error(view, status); return; } status = B_ERROR; if (!msgr.LockTarget()) { Error(view, status); return; } status = B_BAD_HANDLER; view = dynamic_cast<BPoseView *>(msgr.Target(NULL)); if (!view) { Error(view, status); return; } if (dynamic_cast<BWindow *>(view->Looper()) == NULL) { Error(view, status, true); return; } windowTitleBackup = view->Window()->Title(); view->SaveColumnState(poseViewColumnBackup); view->SaveState(poseViewBackup); view->SetDragEnabled(false); view->SetSelectionRectEnabled(false); view->SetPoseEditing(false); poseViewModeBackup = view->ViewMode(); view->SetViewMode(kIconMode); view->ShowBarberPole(); view->UnlockLooper(); alert = new BAlert("Error", "IconVader:\nClick on the icons to get points." "\nAvoid symlinks!", "OK"); alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); alert->Go(); int32 score = 0; int32 count = 300; while (count--) { status = B_ERROR; if (!msgr.LockTarget()) { Error(view, status); return; } BPose *pose; for (int32 i = 0; (pose = view->PoseAtIndex(i)); i++) { if (pose->IsSelected()) { if (pose->TargetModel()->IsFile()) score++; if (pose->TargetModel()->IsDirectory()) score+=2; if (pose->TargetModel()->IsSymLink()) score-=10; pose->Select(false); } #ifdef __HAIKU__ BPoint location = pose->Location(view); #else BPoint location = pose->Location(); #endif location.x += ((rand() % 20) - 10); location.y += ((rand() % 20) - 10); #ifdef __HAIKU__ pose->SetLocation(location, view); #else pose->SetLocation(location); #endif } view->CheckPoseVisibility(); view->Invalidate(); BString str("Score: "); str << score; view->Window()->SetTitle(str.String()); view->UnlockLooper(); snooze(100000); } BString scoreStr("You scored "); scoreStr << score << " points!"; alert = new BAlert("Error", scoreStr.String(), "Cool!"); alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); alert->Go(); status = B_ERROR; if (!msgr.LockTarget()) { Error(view, status); return; } /* status = B_BAD_HANDLER; view = dynamic_cast<BPoseView *>(msgr.Target(NULL)); if (!view) goto err1; */ view->HideBarberPole(); view->SetViewMode(poseViewModeBackup); view->RestoreState(poseViewBackup); view->RestoreColumnState(poseViewColumnBackup); view->Window()->SetTitle(windowTitleBackup.String()); /* BMessage('_RRC') { TrackerViewToken = BMessenger(port=32004, team=591, target=direct:0x131) } */ //be_roster->Launch("application/x-vnd.haiku-filetypes", refs); view->UnlockLooper(); return; }