bool FavoritesMenu::AddNextItem() { // run the next chunk of code for a given item adding state if (fState == kStart) { fState = kAddingFavorites; fSectionItemCount = 0; fAddedSeparatorForSection = false; // set up adding the GoTo menu items try { BPath path; ThrowOnError(find_directory(B_USER_SETTINGS_DIRECTORY, &path, true)); path.Append(kGoDirectory); mkdir(path.Path(), 0777); BEntry entry(path.Path()); Model startModel(&entry, true); ThrowOnInitCheckError(&startModel); if (!startModel.IsContainer()) throw B_ERROR; if (startModel.IsQuery()) fContainer = new QueryEntryListCollection(&startModel); else if (startModel.IsVirtualDirectory()) fContainer = new VirtualDirectoryEntryList(&startModel); else { fContainer = new DirectoryEntryList(*dynamic_cast<BDirectory*> (startModel.Node())); } ThrowOnInitCheckError(fContainer); ThrowOnError( fContainer->Rewind() ); } catch (...) { delete fContainer; fContainer = NULL; } } if (fState == kAddingFavorites) { entry_ref ref; if (fContainer != NULL && fContainer->GetNextRef(&ref) == B_OK) { Model model(&ref, true); if (model.InitCheck() != B_OK) return true; if (!ShouldShowModel(&model)) return true; BMenuItem* item = BNavMenu::NewModelItem(&model, model.IsDirectory() ? fOpenFolderMessage : fOpenFileMessage, fTarget); if (item == NULL) return true; item->SetLabel(ref.name); // this is the name of the link in the Go dir if (!fAddedSeparatorForSection) { fAddedSeparatorForSection = true; AddItem(new TitledSeparatorItem(B_TRANSLATE("Favorites"))); } fUniqueRefCheck.push_back(*model.EntryRef()); AddItem(item); fSectionItemCount++; return true; } // done with favorites, set up for adding recent files fState = kAddingFiles; fAddedSeparatorForSection = false; app_info info; be_app->GetAppInfo(&info); fItems.MakeEmpty(); int32 apps, docs, folders; TrackerSettings().RecentCounts(&apps, &docs, &folders); BRoster().GetRecentDocuments(&fItems, docs, NULL, info.signature); fIndex = 0; fSectionItemCount = 0; } if (fState == kAddingFiles) { // if this is a Save panel, not an Open panel // then don't add the recent documents if (!fIsSavePanel) { for (;;) { entry_ref ref; if (fItems.FindRef("refs", fIndex++, &ref) != B_OK) break; Model model(&ref, true); if (model.InitCheck() != B_OK) return true; if (!ShouldShowModel(&model)) return true; BMenuItem* item = BNavMenu::NewModelItem(&model, fOpenFileMessage, fTarget); if (item) { if (!fAddedSeparatorForSection) { fAddedSeparatorForSection = true; AddItem(new TitledSeparatorItem( B_TRANSLATE("Recent documents"))); } AddItem(item); fSectionItemCount++; return true; } } } // done with recent files, set up for adding recent folders fState = kAddingFolders; fAddedSeparatorForSection = false; app_info info; be_app->GetAppInfo(&info); fItems.MakeEmpty(); int32 apps, docs, folders; TrackerSettings().RecentCounts(&apps, &docs, &folders); BRoster().GetRecentFolders(&fItems, folders, info.signature); fIndex = 0; } if (fState == kAddingFolders) { for (;;) { entry_ref ref; if (fItems.FindRef("refs", fIndex++, &ref) != B_OK) break; // don't add folders that are already in the GoTo section if (find_if(fUniqueRefCheck.begin(), fUniqueRefCheck.end(), bind2nd(std::equal_to<entry_ref>(), ref)) != fUniqueRefCheck.end()) { continue; } Model model(&ref, true); if (model.InitCheck() != B_OK) return true; if (!ShouldShowModel(&model)) return true; BMenuItem* item = BNavMenu::NewModelItem(&model, fOpenFolderMessage, fTarget, true); if (item != NULL) { if (!fAddedSeparatorForSection) { fAddedSeparatorForSection = true; AddItem(new TitledSeparatorItem( B_TRANSLATE("Recent folders"))); } AddItem(item); item->SetEnabled(true); // BNavMenu::NewModelItem returns a disabled item here - // need to fix this in BNavMenu::NewModelItem return true; } } } return false; }
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; } }
void TTracker::OpenContainerWindow(Model* model, BMessage* originalRefsList, OpenSelector openSelector, uint32 openFlags, bool checkAlreadyOpen, const BMessage* stateMessage) { AutoLock<WindowList> lock(&fWindowList); BContainerWindow* window = NULL; const node_ref* modelNodeRef = model->NodeRef(); if (checkAlreadyOpen && openSelector != kRunOpenWithWindow) { // find out if window already open window = FindContainerWindow(modelNodeRef); } bool someWindowActivated = false; uint32 workspace = (uint32)(1 << current_workspace()); int32 windowCount = 0; while (window != NULL) { if ((window->Workspaces() & workspace) != 0 && (dynamic_cast<BDeskWindow*>(window) == NULL || !TrackerSettings().SingleWindowBrowse())) { // We found at least one window that is open and is not Desktop // or we're in spatial mode, activate it and make sure we don't // jerk the workspaces around. window->Activate(); someWindowActivated = true; } window = FindContainerWindow(model->NodeRef(), ++windowCount); } if (someWindowActivated) { delete model; return; } // If no window was activated (none in the current workspace), // we open a new one. if (openSelector == kRunOpenWithWindow) { BMessage* refList = NULL; if (originalRefsList == NULL) { // when passing just a single model, stuff it's entry in a single // element list anyway ASSERT(model != NULL); refList = new BMessage; refList->AddRef("refs", model->EntryRef()); delete model; model = NULL; } else { // clone the message, window adopts it for it's own use refList = new BMessage(*originalRefsList); } window = new OpenWithContainerWindow(refList, &fWindowList); } else if (model->IsQuery()) { // window will adopt the model window = new BQueryContainerWindow(&fWindowList, openFlags); } else if (model->IsVirtualDirectory()) { // window will adopt the model window = new VirtualDirectoryWindow(&fWindowList, openFlags); } else { // window will adopt the model window = new BContainerWindow(&fWindowList, openFlags); } if (model != NULL) window->CreatePoseView(model); BMessage restoreStateMessage(kRestoreState); if (stateMessage != NULL) restoreStateMessage.AddMessage("state", stateMessage); window->PostMessage(&restoreStateMessage); }
TTracker::TTracker() : BApplication(kTrackerSignature), fMimeTypeList(NULL), fClipboardRefsWatcher(NULL), fTrashWatcher(NULL), fTaskLoop(NULL), fNodeMonitorCount(-1), fWatchingInterface(new WatchingInterface), fSettingsWindow(NULL) { BPathMonitor::SetWatchingInterface(fWatchingInterface); // set the cwd to /boot/home, anything that's launched // from Tracker will automatically inherit this BPath homePath; if (find_directory(B_USER_DIRECTORY, &homePath) == B_OK) chdir(homePath.Path()); // ask for a bunch more file descriptors so that nested copying works well struct rlimit rl; rl.rlim_cur = 512; rl.rlim_max = RLIM_SAVED_MAX; setrlimit(RLIMIT_NOFILE, &rl); fNodeMonitorCount = DEFAULT_MON_NUM; gLocalizedNamePreferred = BLocaleRoster::Default()->IsFilesystemTranslationPreferred(); #ifdef CHECK_OPEN_MODEL_LEAKS InitOpenModelDumping(); #endif InitIconPreloader(); #ifdef LEAK_CHECKING SetNewLeakChecking(true); SetMallocLeakChecking(true); #endif // This is how often it should update the free space bar on the // volume icons SetPulseRate(1000000); gLaunchLooper = new LaunchLooper(); gLaunchLooper->Run(); // open desktop window BContainerWindow* deskWindow = NULL; BDirectory deskDir; if (FSGetDeskDir(&deskDir) == B_OK) { // create desktop BEntry entry; deskDir.GetEntry(&entry); Model* model = new Model(&entry, true); if (model->InitCheck() == B_OK) { AutoLock<WindowList> lock(&fWindowList); deskWindow = new BDeskWindow(&fWindowList); AutoLock<BWindow> windowLock(deskWindow); deskWindow->CreatePoseView(model); deskWindow->Init(); if (TrackerSettings().ShowDisksIcon()) { // create model for root of everything BEntry entry("/"); Model model(&entry); if (model.InitCheck() == B_OK) { // add the root icon to desktop window BMessage message; message.what = B_NODE_MONITOR; message.AddInt32("opcode", B_ENTRY_CREATED); message.AddInt32("device", model.NodeRef()->device); message.AddInt64("node", model.NodeRef()->node); message.AddInt64("directory", model.EntryRef()->directory); message.AddString("name", model.EntryRef()->name); deskWindow->PostMessage(&message, deskWindow->PoseView()); } } } else delete model; } }
void TTracker::_OpenPreviouslyOpenedWindows(const char* pathFilter) { size_t filterLength = 0; if (pathFilter != NULL) filterLength = strlen(pathFilter); BDirectory deskDir; attr_info attrInfo; if (FSGetDeskDir(&deskDir) != B_OK || deskDir.GetAttrInfo(kAttrOpenWindows, &attrInfo) != B_OK) { return; } char* buffer = (char*)malloc((size_t)attrInfo.size); BMessage message; if (deskDir.ReadAttr(kAttrOpenWindows, B_MESSAGE_TYPE, 0, buffer, (size_t)attrInfo.size) != attrInfo.size || message.Unflatten(buffer) != B_OK) { free(buffer); return; } free(buffer); node_ref nodeRef; deskDir.GetNodeRef(&nodeRef); int32 stateMessageCounter = 0; const char* path; for (int32 i = 0; message.FindString("paths", i, &path) == B_OK; i++) { if (strncmp(path, pathFilter, filterLength) != 0) continue; BEntry entry(path, true); if (entry.InitCheck() != B_OK) continue; int8 flags = 0; for (int32 j = 0; message.FindInt8(path, j, &flags) == B_OK; j++) { Model* model = new Model(&entry); if (model->InitCheck() == B_OK && model->IsContainer()) { BMessage state; bool restoreStateFromMessage = false; if ((flags & kOpenWindowHasState) != 0 && message.FindMessage("window state", stateMessageCounter++, &state) == B_OK) { restoreStateFromMessage = true; } if (restoreStateFromMessage) { OpenContainerWindow(model, 0, kOpen, kRestoreWorkspace | (flags & kOpenWindowMinimized ? kIsHidden : 0U) | kRestoreDecor, false, &state); } else { OpenContainerWindow(model, 0, kOpen, kRestoreWorkspace | (flags & kOpenWindowMinimized ? kIsHidden : 0U) | kRestoreDecor); } } else delete model; } } // open disks window if needed if (pathFilter == NULL && TrackerSettings().ShowDisksIcon() && message.HasBool("open_disks_window")) { BEntry entry("/"); Model* model = new Model(&entry); if (model->InitCheck() == B_OK) OpenContainerWindow(model, 0, kOpen, kRestoreWorkspace); else delete model; } }
void BPose::DrawBar(BPoint where, BView* view, icon_size which) { view->PushState(); int32 size; int32 barWidth; int32 barHeight; int32 yOffset; if (which >= B_LARGE_ICON) { size = which - 1; barWidth = (int32)(7.0f / 32.0f * (float)which); yOffset = 2; barHeight = size - 4 - 2 * yOffset; } else { size = B_MINI_ICON; barWidth = 4; yOffset = 0; barHeight = size - 4 - 2 * yOffset; } // the black shadowed line view->SetHighColor(32, 32, 32, 92); view->MovePenTo(BPoint(where.x + size, where.y + 1 + yOffset)); view->StrokeLine(BPoint(where.x + size, where.y + size - yOffset)); view->StrokeLine(BPoint(where.x + size - barWidth + 1, where.y + size - yOffset)); view->SetDrawingMode(B_OP_ALPHA); // the gray frame view->SetHighColor(76, 76, 76, 192); BRect rect(where.x + size - barWidth,where.y + yOffset, where.x + size - 1,where.y + size - 1 - yOffset); view->StrokeRect(rect); // calculate bar height int32 percent = fPercent > -1 ? fPercent : -2 - fPercent; int32 barPos = int32(barHeight * percent / 100.0); if (barPos < 0) barPos = 0; else if (barPos > barHeight) barPos = barHeight; // the free space bar view->SetHighColor(TrackerSettings().FreeSpaceColor()); rect.InsetBy(1,1); BRect bar(rect); bar.bottom = bar.top + barPos - 1; if (barPos > 0) view->FillRect(bar); // the used space bar bar.top = bar.bottom + 1; bar.bottom = rect.bottom; view->SetHighColor(fPercent < -1 ? TrackerSettings().WarningSpaceColor() : TrackerSettings().UsedSpaceColor()); view->FillRect(bar); view->PopState(); }