Tracker: Allow draggable container icon on Root, Trash and Printers

Use new DraggableContainerIcon name when invalidating icon.

Create a ShouldHaveDraggableFolderIcon() method on BContainerWindow
to consolidate the gating logic to a method.

We alert if you try and copy, move or create link to any of these
directories, however you may drag the icon in some instances such as
to change the directory in a file panel or to open the directory up
in FileTypes. You may create a link to the printers directory.

Set the Printer icon on the printers directory.

Fixes #3385

Tracker: Disks menu in CountView

* Open Disks directory on click.
* Skip volumes with no capacity (e.g. system, config) from
  Root and Desktop menus (still shown in Home and volumes though).
* No Trash on volumes, add only to Desktop.
* Declare some variables outside loop.
* Rename originatingWindow to source.

Fixes #3549

Change-Id: I66318d2485a5a8405f5459c355a467f34e19ecc5
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9499
Reviewed-by: John Scipione <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
John Scipione
2025-07-30 04:07:05 +00:00
parent f1cc4cf8cb
commit e32d782cb4
14 changed files with 181 additions and 130 deletions
+2 -2
View File
@@ -49,11 +49,11 @@ public:
const char* entryName = 0); const char* entryName = 0);
virtual ~BDirMenu(); virtual ~BDirMenu();
void Populate(const BEntry* startDir, BWindow* originatingWindow, void Populate(const BEntry* startDir, BWindow* source,
bool includeStartDir = false, bool select = false, bool includeStartDir = false, bool select = false,
bool reverse = false, bool addShortcuts = false, bool reverse = false, bool addShortcuts = false,
bool navMenuEntries = false); bool navMenuEntries = false);
void AddItemToDirMenu(const BEntry*, BWindow* originatingWindow, void AddItemToDirMenu(const BEntry*, BWindow* source,
bool atEnd, bool addShortcuts, bool navMenuEntries = false); bool atEnd, bool addShortcuts, bool navMenuEntries = false);
void AddDisksIconToMenu(bool reverse = false); void AddDisksIconToMenu(bool reverse = false);
+21 -17
View File
@@ -761,7 +761,7 @@ BContainerWindow::Init(const BMessage* message)
fMenuContainer->GroupLayout()->AddView(fMenuBar); fMenuContainer->GroupLayout()->AddView(fMenuBar);
AddMenus(); AddMenus();
if (!TargetModel()->IsRoot() && !TargetModel()->IsTrash()) if (ShouldHaveDraggableFolderIcon())
_AddFolderIcon(); _AddFolderIcon();
} else { } else {
// add equivalents of the menu shortcuts to the menuless // add equivalents of the menu shortcuts to the menuless
@@ -997,23 +997,20 @@ BContainerWindow::SwitchDirectory(const entry_ref* ref)
SetSingleWindowBrowseShortcuts(settings.SingleWindowBrowse()); SetSingleWindowBrowseShortcuts(settings.SingleWindowBrowse());
// Update draggable folder icon // Update draggable folder icon
if (fMenuBar != NULL) { if (ShouldHaveDraggableFolderIcon()) {
if (!TargetModel()->IsRoot() && !TargetModel()->IsTrash()) { // Folder icon should be visible, but in single
// Folder icon should be visible, but in single // window navigation, it might not be.
// window navigation, it might not be. if (fDraggableIcon != NULL) {
if (fDraggableIcon != NULL) { IconCache::sIconCache->IconChanged(TargetModel());
IconCache::sIconCache->IconChanged(TargetModel()); if (fDraggableIcon->IsHidden())
if (fDraggableIcon->IsHidden()) fDraggableIcon->Show();
fDraggableIcon->Show(); fDraggableIcon->Invalidate();
fDraggableIcon->Invalidate(); } else {
} else { // draggable icon visible
// draggable icon visible _AddFolderIcon();
_AddFolderIcon();
}
} else if (fDraggableIcon != NULL) {
// hide for Root or Trash
fDraggableIcon->Hide();
} }
} else if (fMenuBar != NULL && fDraggableIcon != NULL) {
fDraggableIcon->Hide();
} }
UpdateTitle(); UpdateTitle();
@@ -3153,6 +3150,13 @@ BContainerWindow::ShouldHaveAddOnMenus()
} }
bool
BContainerWindow::ShouldHaveDraggableFolderIcon()
{
return fMenuBar != NULL;
}
// #pragma mark - BContainerWindow private methods // #pragma mark - BContainerWindow private methods
+4
View File
@@ -301,6 +301,10 @@ protected:
bool ShouldHaveNewFolderItem(); bool ShouldHaveNewFolderItem();
bool ShouldHaveAddOnMenus(); bool ShouldHaveAddOnMenus();
public:
virtual bool ShouldHaveDraggableFolderIcon();
protected:
BGroupLayout* fRootLayout; BGroupLayout* fRootLayout;
BGroupView* fMenuContainer; BGroupView* fMenuContainer;
BGridView* fPoseContainer; BGridView* fPoseContainer;
+22 -24
View File
@@ -74,8 +74,13 @@ BCountView::BCountView(BPoseView* view)
fTypeAheadString(""), fTypeAheadString(""),
fFilterString("") fFilterString("")
{ {
GetTrackerResources()->GetBitmapResource(B_MESSAGE_TYPE, GetTrackerResources()->GetBitmapResource(B_MESSAGE_TYPE, R_BarberPoleBitmap, &fBarberPoleMap);
R_BarberPoleBitmap, &fBarberPoleMap);
SetFont(be_plain_font);
SetFontSize(std::max(kMinFontSize, ceilf(be_plain_font->Size() * 0.75f)));
SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
SetLowUIColor(ViewUIColor());
} }
@@ -291,35 +296,28 @@ BCountView::MouseDown(BPoint)
if (fPoseView->IsFilePanel() || fPoseView->TargetModel() == NULL) if (fPoseView->IsFilePanel() || fPoseView->TargetModel() == NULL)
return; return;
if (!window->TargetModel()->IsRoot()) { if (window->TargetModel()->IsRoot())
BDirMenu* menu = new BDirMenu(NULL, be_app, B_REFS_RECEIVED); return;
BEntry entry;
if (entry.SetTo(window->TargetModel()->EntryRef()) == B_OK)
menu->Populate(&entry, Window(), false, false, true, false, true);
else
menu->Populate(NULL, Window(), false, false, true, false, true);
BPoint point = Bounds().LeftBottom(); BDirMenu menu(NULL, be_app, B_REFS_RECEIVED);
point.y += 3; BEntry entry;
ConvertToScreen(&point); if (entry.SetTo(window->TargetModel()->EntryRef()) == B_OK)
BRect clickToOpenRect(Bounds()); menu.Populate(&entry, Window(), false, false, true, false, true);
ConvertToScreen(&clickToOpenRect); else
menu->Go(point, true, true, clickToOpenRect); menu.Populate(NULL, Window(), false, false, true, false, true);
delete menu;
} BPoint point = Bounds().LeftBottom();
point.y += 3;
ConvertToScreen(&point);
BRect clickToOpenRect(Bounds());
ConvertToScreen(&clickToOpenRect);
menu.Go(point, true, true, clickToOpenRect);
} }
void void
BCountView::AttachedToWindow() BCountView::AttachedToWindow()
{ {
SetFont(be_plain_font);
SetFontSize(std::max(kMinFontSize,
ceilf(be_plain_font->Size() * 0.75f)));
SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
SetLowUIColor(ViewUIColor());
CheckCount(); CheckCount();
} }
+2
View File
@@ -70,6 +70,8 @@ public:
void SaveDesktopPoseLocations(); void SaveDesktopPoseLocations();
virtual bool ShouldHaveDraggableFolderIcon() { return false; };
protected: protected:
virtual BPoseView* NewPoseView(Model*, uint32); virtual BPoseView* NewPoseView(Model*, uint32);
+22 -21
View File
@@ -83,7 +83,7 @@ BDirMenu::~BDirMenu()
void void
BDirMenu::Populate(const BEntry* startEntry, BWindow* originatingWindow, BDirMenu::Populate(const BEntry* startEntry, BWindow* source,
bool includeStartEntry, bool select, bool reverse, bool addShortcuts, bool includeStartEntry, bool select, bool reverse, bool addShortcuts,
bool navMenuEntries) bool navMenuEntries)
{ {
@@ -96,7 +96,7 @@ BDirMenu::Populate(const BEntry* startEntry, BWindow* originatingWindow,
ModelMenuItem* menu = NULL; ModelMenuItem* menu = NULL;
if (fMenuBar) { if (fMenuBar != NULL) {
menu = new ModelMenuItem(&model, this, true, true); menu = new ModelMenuItem(&model, this, true, true);
fMenuBar->AddItem(menu); fMenuBar->AddItem(menu);
} }
@@ -115,8 +115,7 @@ BDirMenu::Populate(const BEntry* startEntry, BWindow* originatingWindow,
BDirectory parent; BDirectory parent;
BDirectory dir(&entry); BDirectory dir(&entry);
if (!showDesktop && dir.InitCheck() == B_OK if (!showDesktop && dir.InitCheck() == B_OK && dir.IsRootDirectory()) {
&& dir.IsRootDirectory()) {
// if we're at the root directory skip "mnt" and // if we're at the root directory skip "mnt" and
// go straight to "/" // go straight to "/"
parent.SetTo("/"); parent.SetTo("/");
@@ -143,8 +142,7 @@ BDirMenu::Populate(const BEntry* startEntry, BWindow* originatingWindow,
bool hitRoot = false; bool hitRoot = false;
BDirectory dir(&entry); BDirectory dir(&entry);
if (!showDesktop && dir.InitCheck() == B_OK if (!showDesktop && dir.InitCheck() == B_OK && dir.IsRootDirectory()) {
&& dir.IsRootDirectory()) {
// if we're at the root directory skip "mnt" and // if we're at the root directory skip "mnt" and
// go straight to "/" // go straight to "/"
hitRoot = true; hitRoot = true;
@@ -167,8 +165,7 @@ BDirMenu::Populate(const BEntry* startEntry, BWindow* originatingWindow,
if (result == kReadAttrFailed || !info.fInvisible if (result == kReadAttrFailed || !info.fInvisible
|| (showDesktop && desktopEntry == entry)) { || (showDesktop && desktopEntry == entry)) {
AddItemToDirMenu(&entry, originatingWindow, reverse, AddItemToDirMenu(&entry, source, reverse, addShortcuts, navMenuEntries);
addShortcuts, navMenuEntries);
} }
if (hitRoot) { if (hitRoot) {
@@ -186,8 +183,7 @@ BDirMenu::Populate(const BEntry* startEntry, BWindow* originatingWindow,
if (!select) if (!select)
return; return;
ModelMenuItem* item ModelMenuItem* item = dynamic_cast<ModelMenuItem*>(ItemAt(CountItems() - 1));
= dynamic_cast<ModelMenuItem*>(ItemAt(CountItems() - 1));
if (item != NULL) { if (item != NULL) {
item->SetMarked(true); item->SetMarked(true);
if (menu) { if (menu) {
@@ -207,7 +203,7 @@ BDirMenu::Populate(const BEntry* startEntry, BWindow* originatingWindow,
void void
BDirMenu::AddItemToDirMenu(const BEntry* entry, BWindow* originatingWindow, BDirMenu::AddItemToDirMenu(const BEntry* entry, BWindow* source,
bool atEnd, bool addShortcuts, bool navMenuEntries) bool atEnd, bool addShortcuts, bool navMenuEntries)
{ {
Model model(entry); Model model(entry);
@@ -219,16 +215,14 @@ BDirMenu::AddItemToDirMenu(const BEntry* entry, BWindow* originatingWindow,
// add reference to the container windows model so that we can // add reference to the container windows model so that we can
// close the window if // close the window if
BContainerWindow* window = originatingWindow ? BContainerWindow* window = dynamic_cast<BContainerWindow*>(source);
dynamic_cast<BContainerWindow*>(originatingWindow) : 0;
if (window != NULL) { if (window != NULL) {
message->AddData("nodeRefsToClose", B_RAW_TYPE, message->AddData("nodeRefsToClose", B_RAW_TYPE,
window->TargetModel()->NodeRef(), sizeof (node_ref)); window->TargetModel()->NodeRef(), sizeof(node_ref));
} }
ModelMenuItem* item; ModelMenuItem* item;
if (navMenuEntries) { if (navMenuEntries) {
BNavMenu* subMenu = new BNavMenu(model.Name(), B_REFS_RECEIVED, BNavMenu* subMenu = new BNavMenu(model.Name(), fCommand, fTarget, source);
fTarget, window);
entry_ref ref; entry_ref ref;
entry->GetRef(&ref); entry->GetRef(&ref);
subMenu->SetNavDir(&ref); subMenu->SetNavDir(&ref);
@@ -254,8 +248,7 @@ BDirMenu::AddItemToDirMenu(const BEntry* entry, BWindow* originatingWindow,
item->SetTarget(fTarget); item->SetTarget(fTarget);
if (fMenuBar != NULL) { if (fMenuBar != NULL) {
ModelMenuItem* menu ModelMenuItem* menu = dynamic_cast<ModelMenuItem*>(fMenuBar->ItemAt(0));
= dynamic_cast<ModelMenuItem*>(fMenuBar->ItemAt(0));
if (menu != NULL) { if (menu != NULL) {
ThrowOnError(menu->SetEntry(entry)); ThrowOnError(menu->SetEntry(entry));
item->SetMarked(true); item->SetMarked(true);
@@ -272,13 +265,21 @@ BDirMenu::AddDisksIconToMenu(bool atEnd)
if (model.InitCheck() != B_OK) if (model.InitCheck() != B_OK)
return; return;
entry_ref ref;
entry.GetRef(&ref);
BMessage* message = new BMessage(fCommand); BMessage* message = new BMessage(fCommand);
message->AddRef(fEntryName.String(), model.EntryRef()); message->AddRef(fEntryName.String(), &ref);
BNavMenu* subMenu = new BNavMenu(model.Name(), fCommand, fTarget);
subMenu->SetNavDir(&ref);
ModelMenuItem* item = new ModelMenuItem(&model, subMenu);
item->SetLabel(model.Name());
item->SetMessage(message);
ModelMenuItem* item = new ModelMenuItem(&model,
B_TRANSLATE(B_DISKS_DIR_NAME), message);
if (atEnd) if (atEnd)
AddItem(item); AddItem(item);
else else
AddItem(item, 0); AddItem(item, 0);
item->SetTarget(fTarget);
} }
+1 -2
View File
@@ -71,8 +71,7 @@ DraggableContainerIcon::MouseDown(BPoint where)
if (window == NULL) if (window == NULL)
return; return;
// we don't like the Trash icon (because it cannot be moved) if (!window->ShouldHaveDraggableFolderIcon())
if (window->TargetModel()->IsTrash() || window->TargetModel()->IsPrintersDir())
return; return;
if (window->CurrentMessage() == NULL) if (window->CurrentMessage() == NULL)
+33 -15
View File
@@ -624,7 +624,7 @@ ConfirmChangeIfWellKnownDirectory(const BEntry* entry, DestructiveAction action,
if (confirmedAlready && *confirmedAlready == kConfirmedAll) if (confirmedAlready && *confirmedAlready == kConfirmedAll)
return true; return true;
if (FSIsDeskDir(entry) || FSIsTrashDir(entry) || FSIsRootDir(entry)) if (FSIsDeskDir(entry) || FSIsPrintersDir(entry) || FSIsRootDir(entry) || FSIsTrashDir(entry))
return false; return false;
if ((!DirectoryMatchesOrContains(entry, B_SYSTEM_DIRECTORY) if ((!DirectoryMatchesOrContains(entry, B_SYSTEM_DIRECTORY)
@@ -891,26 +891,44 @@ InitCopy(CopyLoopControl* loopControl, uint32 moveMode,
BEntry entry((entry_ref*)srcList->ItemAt(index)); BEntry entry((entry_ref*)srcList->ItemAt(index));
if (FSIsRootDir(&entry)) { if (FSIsRootDir(&entry)) {
BString errorStr; BString errorStr;
if (moveMode == kCreateLink) { if (moveMode == kCreateLink || moveMode == kCreateRelativeLink)
errorStr.SetTo( errorStr.SetTo(B_TRANSLATE("You cannot create a link to the root directory."));
B_TRANSLATE("You cannot create a link to the root " else
"directory.")); errorStr.SetTo(B_TRANSLATE("You cannot copy or move the root directory."));
} else {
errorStr.SetTo(
B_TRANSLATE("You cannot copy or move the root "
"directory."));
}
BAlert* alert = new BAlert("", errorStr.String(), BAlert* alert = new BAlert("", errorStr.String(), B_TRANSLATE("Cancel"), 0, 0,
B_TRANSLATE("Cancel"), 0, 0, B_WIDTH_AS_USUAL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
B_WARNING_ALERT);
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
alert->Go(); alert->Go();
return B_ERROR;
} else if (FSIsTrashDir(&entry)) {
BString errorStr;
if (moveMode == kCreateLink || moveMode == kCreateRelativeLink)
errorStr.SetTo(B_TRANSLATE("You cannot create a link to the Trash directory."));
else
errorStr.SetTo(B_TRANSLATE("You cannot copy or move the Trash directory."));
BAlert* alert = new BAlert("", errorStr.String(), B_TRANSLATE("Cancel"), 0, 0,
B_WIDTH_AS_USUAL, B_WARNING_ALERT);
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
alert->Go();
return B_ERROR;
} else if (FSIsPrintersDir(&entry)
&& (moveMode == kCopySelectionTo || moveMode == kMoveSelectionTo)) {
BString errorStr(B_TRANSLATE("You cannot copy or move the Printers directory."));
BAlert* alert = new BAlert("", errorStr.String(), B_TRANSLATE("Cancel"), 0, 0,
B_WIDTH_AS_USUAL, B_WARNING_ALERT);
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
alert->Go();
return B_ERROR; return B_ERROR;
} }
if (moveMode == kMoveSelectionTo if (moveMode == kMoveSelectionTo
&& !ConfirmChangeIfWellKnownDirectory(&entry, kMove, && !ConfirmChangeIfWellKnownDirectory(&entry, kMove, false, &askOnceOnly)) {
false, &askOnceOnly)) {
return B_ERROR; return B_ERROR;
} }
} }
+2
View File
@@ -104,6 +104,8 @@ public:
// a default state file the last time it ran. // a default state file the last time it ran.
bool DefaultStateRestored() const { return fDefaultStateRestored; } bool DefaultStateRestored() const { return fDefaultStateRestored; }
virtual bool ShouldHaveDraggableFolderIcon() { return false; };
protected: protected:
BPoseView* NewPoseView(Model* model, uint32); BPoseView* NewPoseView(Model* model, uint32);
virtual void Init(const BMessage* message = NULL); virtual void Init(const BMessage* message = NULL);
+25
View File
@@ -667,6 +667,22 @@ IconCache::GetRootIcon(AutoLock<SimpleIconCache>*,
} }
IconCacheEntry*
IconCache::GetPrinterIcon(AutoLock<SimpleIconCache>*,
AutoLock<SimpleIconCache>* sharedCacheLocker,
AutoLock<SimpleIconCache>** resultingOpenCache,
Model*, IconSource &source, IconDrawMode mode,
BSize size, LazyBitmapAllocator* lazyBitmap)
{
*resultingOpenCache = sharedCacheLocker;
(*resultingOpenCache)->Lock();
source = kTrackerSupplied;
return GetIconFromMetaMime(B_PRINTER_MIMETYPE, mode, size, lazyBitmap, 0);
}
IconCacheEntry* IconCacheEntry*
IconCache::GetWellKnownIcon(AutoLock<SimpleIconCache>*, IconCache::GetWellKnownIcon(AutoLock<SimpleIconCache>*,
AutoLock<SimpleIconCache>* sharedCacheLocker, AutoLock<SimpleIconCache>* sharedCacheLocker,
@@ -945,6 +961,10 @@ IconCache::Preload(AutoLock<SimpleIconCache>* nodeCacheLocker,
&resultingOpenCache, model, source, mode, &resultingOpenCache, model, source, mode,
size, &lazyBitmap); size, &lazyBitmap);
} }
} else if (model->IsPrintersDir()) {
entry = GetPrinterIcon(nodeCacheLocker, sharedCacheLocker,
&resultingOpenCache, model, source, mode, size, &lazyBitmap);
ASSERT(entry != NULL);
} else { } else {
if (source == kUnknownSource) { if (source == kUnknownSource) {
// look for node icons first // look for node icons first
@@ -1001,6 +1021,11 @@ IconCache::Preload(AutoLock<SimpleIconCache>* nodeCacheLocker,
&resultingOpenCache, model, source, mode, size, &resultingOpenCache, model, source, mode, size,
&lazyBitmap); &lazyBitmap);
break; break;
} else if (model->IsPrintersDir()) {
entry = GetPrinterIcon(nodeCacheLocker, sharedCacheLocker,
&resultingOpenCache, model, source, mode, size,
&lazyBitmap);
break;
} else { } else {
entry = GetWellKnownIcon(nodeCacheLocker, entry = GetWellKnownIcon(nodeCacheLocker,
sharedCacheLocker, &resultingOpenCache, model, sharedCacheLocker, &resultingOpenCache, model,
+5
View File
@@ -446,6 +446,11 @@ private:
AutoLock<SimpleIconCache>** resultingLockedCache, AutoLock<SimpleIconCache>** resultingLockedCache,
Model*, IconSource&, IconDrawMode mode, Model*, IconSource&, IconDrawMode mode,
BSize size, LazyBitmapAllocator*); BSize size, LazyBitmapAllocator*);
IconCacheEntry* GetPrinterIcon(AutoLock<SimpleIconCache>* nodeCache,
AutoLock<SimpleIconCache>* sharedCache,
AutoLock<SimpleIconCache>** resultingLockedCache,
Model*, IconSource&, IconDrawMode mode,
BSize size, LazyBitmapAllocator*);
IconCacheEntry* GetWellKnownIcon(AutoLock<SimpleIconCache> *nodeCache, IconCacheEntry* GetWellKnownIcon(AutoLock<SimpleIconCache> *nodeCache,
AutoLock<SimpleIconCache>* sharedCache, AutoLock<SimpleIconCache>* sharedCache,
AutoLock<SimpleIconCache>** resultingLockedCache, AutoLock<SimpleIconCache>** resultingLockedCache,
+37 -46
View File
@@ -280,11 +280,10 @@ BNavMenu::BNavMenu(const char* title, uint32 message, const BHandler* target,
// add the parent window to the invocation message so that it // add the parent window to the invocation message so that it
// can be closed if option modifier held down during invocation // can be closed if option modifier held down during invocation
BContainerWindow* originatingWindow = BContainerWindow* source = dynamic_cast<BContainerWindow*>(fParentWindow);
dynamic_cast<BContainerWindow*>(fParentWindow); if (source != NULL) {
if (originatingWindow != NULL) {
fMessage.AddData("nodeRefsToClose", B_RAW_TYPE, fMessage.AddData("nodeRefsToClose", B_RAW_TYPE,
originatingWindow->TargetModel()->NodeRef(), sizeof(node_ref)); source->TargetModel()->NodeRef(), sizeof(node_ref));
} }
// too long to have triggers // too long to have triggers
@@ -313,11 +312,10 @@ BNavMenu::BNavMenu(const char* title, uint32 message,
// add the parent window to the invocation message so that it // add the parent window to the invocation message so that it
// can be closed if option modifier held down during invocation // can be closed if option modifier held down during invocation
BContainerWindow* originatingWindow = BContainerWindow* source = dynamic_cast<BContainerWindow*>(fParentWindow);
dynamic_cast<BContainerWindow*>(fParentWindow); if (source != NULL) {
if (originatingWindow != NULL) {
fMessage.AddData("nodeRefsToClose", B_RAW_TYPE, fMessage.AddData("nodeRefsToClose", B_RAW_TYPE,
originatingWindow->TargetModel()->NodeRef(), sizeof (node_ref)); source->TargetModel()->NodeRef(), sizeof(node_ref));
} }
// too long to have triggers // too long to have triggers
@@ -417,9 +415,8 @@ BNavMenu::StartBuildingItemList()
status_t status = entry.GetParent(&parent); status_t status = entry.GetParent(&parent);
// if ref is the root item then build list of volume root dirs // if ref is the root item then build list of volume root dirs
fFlags = uint8((fFlags & ~kVolumesOnly) fFlags = uint8((fFlags & ~kVolumesOnly) | (status == B_ENTRY_NOT_FOUND ? kVolumesOnly : 0));
| (status == B_ENTRY_NOT_FOUND ? kVolumesOnly : 0)); if ((fFlags & kVolumesOnly) != 0)
if (fFlags & kVolumesOnly)
return true; return true;
Model startModel(&entry, true); Model startModel(&entry, true);
@@ -432,9 +429,9 @@ BNavMenu::StartBuildingItemList()
fContainer = new VirtualDirectoryEntryList(&startModel); fContainer = new VirtualDirectoryEntryList(&startModel);
} else if (startModel.IsDesktop()) { } else if (startModel.IsDesktop()) {
fIteratingDesktop = true; fIteratingDesktop = true;
fContainer = DesktopPoseView::InitDesktopDirentIterator(0, fContainer = DesktopPoseView::InitDesktopDirentIterator(0, startModel.EntryRef());
startModel.EntryRef()); if (TrackerSettings().MountVolumesOntoDesktop())
AddRootItemsIfNeeded(); AddRootItemsIfNeeded();
AddTrashItem(); AddTrashItem();
} else if (startModel.IsTrash()) { } else if (startModel.IsTrash()) {
// the trash window needs to display a union of all the // the trash window needs to display a union of all the
@@ -445,26 +442,20 @@ BNavMenu::StartBuildingItemList()
fContainer = new EntryIteratorList(); fContainer = new EntryIteratorList();
while (volRoster.GetNextVolume(&volume) == B_OK) { while (volRoster.GetNextVolume(&volume) == B_OK) {
if (volume.IsReadOnly() || !volume.IsPersistent()) if (volume.IsReadOnly() || !volume.IsPersistent() || volume.Capacity() == 0)
continue; continue;
BDirectory trashDir; BDirectory trashDir;
if (FSGetTrashDir(&trashDir, volume.Device()) == B_OK) { if (FSGetTrashDir(&trashDir, volume.Device()) == B_OK) {
EntryIteratorList* iteratorList EntryIteratorList* iteratorList = dynamic_cast<EntryIteratorList*>(fContainer);
= dynamic_cast<EntryIteratorList*>(fContainer);
ASSERT(iteratorList != NULL); ASSERT(iteratorList != NULL);
if (iteratorList != NULL) if (iteratorList != NULL)
iteratorList->AddItem(new DirectoryEntryList(trashDir)); iteratorList->AddItem(new DirectoryEntryList(trashDir));
} }
} }
} else { } else {
BDirectory* directory = dynamic_cast<BDirectory*>(startModel.Node()); BDirectory* directory = dynamic_cast<BDirectory*>(startModel.Node());
ASSERT(directory != NULL); ASSERT(directory != NULL);
if (directory != NULL) if (directory != NULL)
fContainer = new DirectoryEntryList(*directory); fContainer = new DirectoryEntryList(*directory);
} }
@@ -483,17 +474,19 @@ BNavMenu::AddRootItemsIfNeeded()
{ {
BVolumeRoster roster; BVolumeRoster roster;
roster.Rewind(); roster.Rewind();
BVolume volume; BVolume volume;
BDirectory root;
BEntry entry;
Model model;
while (roster.GetNextVolume(&volume) == B_OK) { while (roster.GetNextVolume(&volume) == B_OK) {
BDirectory root; if (volume.InitCheck() != B_OK || !volume.IsPersistent() || volume.Capacity() == 0
BEntry entry; || volume.GetRootDirectory(&root) != B_OK || root.GetEntry(&entry) != B_OK) {
if (!volume.IsPersistent()
|| volume.GetRootDirectory(&root) != B_OK
|| root.GetEntry(&entry) != B_OK) {
continue; continue;
} }
Model model(&entry); model.SetTo(&entry);
AddOneItem(&model); AddOneItem(&model);
} }
} }
@@ -537,8 +530,11 @@ BNavMenu::AddNextItem()
return true; return true;
} }
QueryEntryListCollection* queryContainer // skip Trash
= dynamic_cast<QueryEntryListCollection*>(fContainer); if (model.IsTrash())
return true;
QueryEntryListCollection* queryContainer = dynamic_cast<QueryEntryListCollection*>(fContainer);
if (queryContainer != NULL && !queryContainer->ShowResultsFromTrash() if (queryContainer != NULL && !queryContainer->ShowResultsFromTrash()
&& FSInTrashDir(model.EntryRef())) { && FSInTrashDir(model.EntryRef())) {
// query entry is in trash and shall not be shown // query entry is in trash and shall not be shown
@@ -547,18 +543,14 @@ BNavMenu::AddNextItem()
ssize_t size = -1; ssize_t size = -1;
PoseInfo poseInfo; PoseInfo poseInfo;
if (model.Node() != NULL) { if (model.Node() != NULL)
size = model.Node()->ReadAttr(kAttrPoseInfo, B_RAW_TYPE, 0, size = model.Node()->ReadAttr(kAttrPoseInfo, B_RAW_TYPE, 0, &poseInfo, sizeof(poseInfo));
&poseInfo, sizeof(poseInfo));
}
model.CloseNode(); model.CloseNode();
// item might be in invisible // item might be in invisible
if (size == sizeof(poseInfo) if (size == sizeof(poseInfo) && !BPoseView::PoseVisible(&model, &poseInfo))
&& !BPoseView::PoseVisible(&model, &poseInfo)) {
return true; return true;
}
AddOneItem(&model); AddOneItem(&model);
@@ -676,16 +668,17 @@ void
BNavMenu::BuildVolumeMenu() BNavMenu::BuildVolumeMenu()
{ {
BVolumeRoster roster; BVolumeRoster roster;
BVolume volume;
roster.Rewind(); roster.Rewind();
BVolume volume;
BDirectory startDir;
BEntry entry;
while (roster.GetNextVolume(&volume) == B_OK) { while (roster.GetNextVolume(&volume) == B_OK) {
if (!volume.IsPersistent()) if (volume.InitCheck() != B_OK || !volume.IsPersistent() || volume.Capacity() == 0)
continue; continue;
BDirectory startDir;
if (volume.GetRootDirectory(&startDir) == B_OK) { if (volume.GetRootDirectory(&startDir) == B_OK) {
BEntry entry;
startDir.GetEntry(&entry); startDir.GetEntry(&entry);
Model* model = new Model(&entry); Model* model = new Model(&entry);
@@ -755,12 +748,10 @@ BNavMenu::DoneBuildingItemList()
if ((fFlags & kShowParent) != 0) { if ((fFlags & kShowParent) != 0) {
BDirectory directory(&fNavDir); BDirectory directory(&fNavDir);
BEntry entry(&fNavDir); BEntry entry(&fNavDir);
if (!directory.IsRootDirectory() if (!directory.IsRootDirectory() && entry.GetParent(&entry) == B_OK) {
&& entry.GetParent(&entry) == B_OK) {
Model model(&entry, true); Model model(&entry, true);
BLooper* looper; BLooper* looper;
AddNavParentDir(&model, fMessage.what, AddNavParentDir(&model, fMessage.what, fMessenger.Target(&looper));
fMessenger.Target(&looper));
} }
} }
+2
View File
@@ -152,6 +152,8 @@ public:
void SetCanSetAppAsDefault(bool); void SetCanSetAppAsDefault(bool);
void SetCanOpen(bool); void SetCanOpen(bool);
virtual bool ShouldHaveDraggableFolderIcon() { return false; };
OpenWithPoseView* PoseView() const; OpenWithPoseView* PoseView() const;
protected: protected:
+3 -3
View File
@@ -5838,14 +5838,14 @@ BPoseView::AttributeChanged(const BMessage* message)
attrName = NULL; attrName = NULL;
Model* targetModel = TargetModel(); Model* targetModel = TargetModel();
if (targetModel != NULL && *targetModel->NodeRef() == itemNode if (ContainerWindow()->ShouldHaveDraggableFolderIcon() && targetModel != NULL
&& targetModel->IsNodeOpen() && *targetModel->NodeRef() == itemNode && targetModel->IsNodeOpen()
&& targetModel->AttrChanged(attrName)) { && targetModel->AttrChanged(attrName)) {
// the icon of our target has changed, update drag icon // the icon of our target has changed, update drag icon
// TODO: make this simpler (i.e. store the icon with the window) // TODO: make this simpler (i.e. store the icon with the window)
BView* view = Window()->FindView("MenuBar"); BView* view = Window()->FindView("MenuBar");
if (view != NULL) { if (view != NULL) {
view = view->FindView("ThisContainer"); view = view->FindView("DraggableContainerIcon");
if (view != NULL) { if (view != NULL) {
IconCache::sIconCache->IconChanged(targetModel); IconCache::sIconCache->IconChanged(targetModel);
view->Invalidate(); view->Invalidate();