BNavMenu::BNavMenu(const char *title, uint32 message, const BMessenger &messenger, BWindow *parentWindow, const BObjectList<BString> *list) : BSlowMenu(title), fMessage(message), fMessenger(messenger), fParentWindow(parentWindow), fFlags(0), fItemList(0), fContainer(0), fTypesList(list) { InitIconPreloader(); SetFont(be_plain_font); // add the parent window to the invocation message so that it // can be closed if option modifier held down during invocation BContainerWindow *originatingWindow = dynamic_cast<BContainerWindow *>(fParentWindow); if (originatingWindow) fMessage.AddData("nodeRefsToClose", B_RAW_TYPE, originatingWindow->TargetModel()->NodeRef(), sizeof (node_ref)); // too long to have triggers SetTriggersEnabled(false); }
void BDirMenu::AddItemToDirMenu(const BEntry* entry, BWindow* originatingWindow, bool atEnd, bool addShortcuts, bool navMenuEntries) { 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; if (navMenuEntries) { BNavMenu* subMenu = new BNavMenu(model.Name(), B_REFS_RECEIVED, fTarget, window); entry_ref ref; entry->GetRef(&ref); subMenu->SetNavDir(&ref); item = new ModelMenuItem(&model, subMenu); item->SetLabel(model.Name()); item->SetMessage(message); } else { item = new ModelMenuItem(&model, model.Name(), message); } if (addShortcuts) { if (model.IsDesktop()) item->SetShortcut('D', B_COMMAND_KEY); else if (FSIsHomeDir(entry)) item->SetShortcut('H', B_COMMAND_KEY); } if (atEnd) AddItem(item); else AddItem(item, 0); item->SetTarget(fTarget); if (fMenuBar) { ModelMenuItem* menu = dynamic_cast<ModelMenuItem*>(fMenuBar->ItemAt(0)); if (menu) { ThrowOnError(menu->SetEntry(entry)); item->SetMarked(true); } } }
void TTracker::CloseWindowAndChildren(const node_ref *node) { BDirectory dir(node); if (dir.InitCheck() != B_OK) return; AutoLock<WindowList> lock(&fWindowList); BObjectList<BContainerWindow> closeList; // make a list of all windows to be closed // count from end to beginning so we can remove items safely for (int32 index = fWindowList.CountItems() - 1; index >= 0; index--) { BContainerWindow *window = dynamic_cast<BContainerWindow *> (fWindowList.ItemAt(index)); if (window && window->TargetModel()) { BEntry wind_entry; wind_entry.SetTo(window->TargetModel()->EntryRef()); if ((*window->TargetModel()->NodeRef() == *node) || dir.Contains(&wind_entry)) { // ToDo: // get rid of the Remove here, BContainerWindow::Quit does it fWindowList.RemoveItemAt(index); closeList.AddItem(window); } } } // now really close the windows int32 numItems = closeList.CountItems(); for (int32 index = 0; index < numItems; index++) { BContainerWindow *window = closeList.ItemAt(index); window->PostMessage(B_CLOSE_REQUESTED); } }
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(); }
void OpenWithMenu::DoneBuildingItemList() { // sort by app name fSupportingAppList->SortItems(SortByRelationAndName, this); // check if each app is unique bool isUnique = true; int32 count = fSupportingAppList->CountItems(); for (int32 index = 0; index < count - 1; index++) { // the list is sorted, just compare two adjacent models if (strcmp(fSupportingAppList->ItemAt(index)->fModel->Name(), fSupportingAppList->ItemAt(index + 1)->fModel->Name()) == 0) { isUnique = false; break; } } // add apps as menu items BFont font; GetFont(&font); int32 lastRelation = -1; for (int32 index = 0; index < count ; index++) { RelationCachingModelProxy* modelProxy = fSupportingAppList->ItemAt(index); Model* model = modelProxy->fModel; BMessage* message = new BMessage(fEntriesToOpen); message->AddRef("handler", model->EntryRef()); BContainerWindow* window = dynamic_cast<BContainerWindow*>(fParentWindow); if (window != NULL) { message->AddData("nodeRefsToClose", B_RAW_TYPE, window->TargetModel()->NodeRef(), sizeof(node_ref)); } BString result; if (isUnique) { // just use the app name result = model->Name(); } else { // get a truncated full path BPath path; BEntry entry(model->EntryRef()); if (entry.GetPath(&path) != B_OK) { PRINT(("stale entry ref %s\n", model->Name())); delete message; continue; } result = path.Path(); font.TruncateString(&result, B_TRUNCATE_MIDDLE, kMaxMenuWidth); } #if DEBUG BString relationDescription; fIterator->RelationDescription(&fEntriesToOpen, model, &relationDescription); result += " ("; result += relationDescription; result += ")"; #endif // divide different relations of opening with a separator int32 relation = modelProxy->Relation(fIterator, &fEntriesToOpen); if (lastRelation != -1 && relation != lastRelation) AddSeparatorItem(); lastRelation = relation; ModelMenuItem* item = new ModelMenuItem(model, result.String(), message); AddItem(item); // mark item if it represents the preferred app if (fHaveCommonPreferredApp && *(model->EntryRef()) == fPreferredRef) { //PRINT(("marking item for % as preferred", model->Name())); item->SetMarked(true); } } // target the menu if (target != NULL) SetTargetForItems(target); else SetTargetForItems(fMessenger); if (CountItems() == 0) { BMenuItem* item = new BMenuItem(B_TRANSLATE("no supporting apps"), 0); item->SetEnabled(false); AddItem(item); } }