Tracker: Shortcuts refactor

Create TShortcuts class that builds shortcut menu items and updates
label, modifiers, enabled status and target. Not every Tracker
shortcut is present but ones used multiple times and many others are.
Update shortcuts in ContainerWindow, DeskWindow, FilePanelPriv,
QueryContainerWindow, VirtualDirectoryWindow and GetInfo HeaderView.

There are two versions of the TShortcuts class, one with a window and
one without. The without-window version is used in the GetInfo window,
everywhere else uses the "smart" window version.

This patch is organizational except fixing two small BeOS bugs:
* Edit query item is always between Open and Open with...
* Repopulate menus when you switch directories in file panels.

Enable "Open parent" item in spatial mode as well as navigation
mode unless in Root, Desktop (Query or Query template) or volume root
if not in "Show disks" mode. Hold down control to override.

BContainerWindow updates:
* Absorb Set...Item() methods into TShortcuts. Add
  UpdateMoveToTrashItem() for "Move to Trash"/"Delete" and many more.
* Absorb ShowContextMenu() improvements from Disks patch.
* Create AddIconSizeMenu() and eliminate duplicate shortcut handling.
  * Put icon size menu in radio mode and refactor item marking.

Replace "New folder" with "New >" menu automatically. Create member
vars and convenience methods to facilitate this. Simplifies building
menus, adding a "New folder" item will automatically be updated to
"New >" if templates are available (except in FilePanel and on the
minimal build you'll just get "New folder").

Refactor Arrange by and Attributes menus. Create support methods.
Create menu on add, populate on update. Do cleanup of detached menu
on Quit().

Refactor SetupOpenWithMenu(). SetupEditQueryItem() got a similar
refactor to be added and removed dynamically. Add FSIsQueriesDir()
to FSUtils used to detect queries directory for Edit query.
* "Edit query" goes between Open and "Open with..." (long story).

UpdateMenu() calls Shortcut()->Update() for all known shortcuts.

Optimize adding/removing dynamic menus so that they are created
and destroyed once and reused again and again.

AddFile...(),    fFile... and "FileContext" becomes
UpdatePose...(), fPose... and "PoseContext".

TTracker changes:
* Skip Desktop in OpenContainerWindow() we setup pose view earlier.
* Move DeskWindow init into DeskWindow constructor and call Init().

DeskWindow changes:
* Replace icon size menu with BContainerWindow::AddIconSizeMenu().
* Remove WindowContextMenu(), handle in BContainerWindow instead.

BPoseView changes:
* Rename kEditItem to kEditName -- better name. Save for Edit someday.
* Use BMessenger::SendMessage() instead of PostMessage(), safer.

BFilePanel updates:
Create the FilePanel menus fresh by overriding the AddMenus() method
instead of copying from BContainerWindow and deleting the items it
doesn't need. This allows us to omit most of the file panel checks.
Add UpdateFileMenu() to update the file menu on RepopulateMenus() and
MenusBeginning().
* Create an AddFavoritesMenu() method and use it to add the menu.
* Override RepopulateMenus() to update just the File and context menus.
* Create Update...Methods() overloading the BContainerWindow versions.
* SetTo() becomes SwitchDirectory()

Unify OpenParent() so that we can call BPoseView::OpenParent() and it
will call the container window or the file panel where appropriate.
Remove BPoseView::ParentIsRoot() and make CanOpenParent() work in both
cases. This means we don't have to check if you are in a file panel or
not when enabling/disabling the "Open parent" item and the Shortcuts
class can simply check CanOpenParent().

Call _inherited SwitchDirectory() to RepopulateMenus() on Root, Trash
and Volumes in FilePanel. This fixes a 25+ year old BeOS bug by
repopulating menus when you switch directories in file panels. Trash,
files in Trash and Root will get the appropriate menu options. For
example "Delete"/"Restore" instead of "Duplicate"/"Move to Trash".

Change-Id: Ic41b148cb6bcf14288cb5588038c13ea12426dc2
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7197
Reviewed-by: John Scipione <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
John Scipione
2025-01-26 18:29:22 +00:00
parent e17a9b1ee0
commit e46d9f45b8
18 changed files with 3259 additions and 1825 deletions
+1 -1
View File
@@ -68,7 +68,7 @@ const uint32 kPasteLinksFromClipboard = 'Tplc';
const uint32 kCancelSelectionToClipboard = 'Tesc';
const uint32 kClipboardPosesChanged = 'Tcpc';
const uint32 kEditItem = 'Tedt';
const uint32 kEditName = 'Tedt';
const uint32 kEditQuery = 'Qedt';
const uint32 kNewFolder = 'Tnwf';
const uint32 kNewEntryFromTemplate = 'Tnwe';
File diff suppressed because it is too large Load Diff
+62 -27
View File
@@ -63,6 +63,8 @@ class Model;
class ModelNodeLazyOpener;
class BorderedView;
class SelectionWindow;
class TShortcuts;
class TemplatesMenu;
#define kDefaultFolderTemplate "DefaultFolderTemplate"
@@ -132,6 +134,7 @@ public:
Model* TargetModel() const;
BPoseView* PoseView() const;
TShortcuts* Shortcuts() const;
BNavigator* Navigator() const;
virtual void SelectionChanged();
@@ -142,6 +145,8 @@ public:
void RestoreStateCommon();
virtual void SaveState(bool hide = true);
virtual void SaveState(BMessage &) const;
virtual void SwitchDirectory(const entry_ref* ref);
virtual void OpenParent();
void UpdateTitle();
bool StateNeedsSaving() const;
@@ -155,21 +160,27 @@ public:
// calls for inheriting window size, attribute layout, etc.
// deprecated
virtual void AddMimeTypesToMenu(BMenu*);
void AddMimeTypesToMenu();
virtual void MarkAttributesMenu(BMenu*);
void MarkAttributesMenu();
void AddMimeTypesToMenu(BMenu*);
BMenuItem* NewArrangeByMenu();
virtual void SetupArrangeByMenu(BMenu*);
void MarkArrangeByMenu(BMenu*);
BMenuItem* NewAttributeMenuItem(const char* label, const char* name,
int32 type, float width, int32 align, bool editable,
bool statField);
BMenuItem* NewAttributeMenuItem(const char* label, const char* name,
int32 type, const char* displayAs, float width, int32 align,
bool editable, bool statField);
virtual void NewAttributesMenu(BMenu*);
void NewAttributesMenu();
virtual void NewAttributesMenu(BMenu*);
void MarkAttributesMenu();
virtual void MarkAttributesMenu(BMenu*);
void HideAttributesMenu();
void ShowAttributesMenu();
PiggybackTaskLoop* DelayedTaskLoop();
// use for RunLater queueing
void PulseTaskLoop();
@@ -196,6 +207,14 @@ public:
void SetPathWatchingEnabled(bool);
bool IsPathWatchingEnabled(void) const;
protected:
enum MenuContext {
kFileMenuContext,
kWindowMenuContext,
kPosePopUpContext,
kWindowPopUpContext
};
protected:
virtual BPoseView* NewPoseView(Model*, uint32);
// instantiate a different flavor of BPoseView for different
@@ -217,42 +236,42 @@ protected:
// desktop window
virtual void AddFileMenu(BMenu* menu);
virtual void AddWindowMenu(BMenu* menu);
virtual void AddIconSizeMenu(BMenu* menu);
virtual void AddContextMenus();
virtual void AddPoseContextMenu(BMenu*);
virtual void AddWindowContextMenu(BMenu*);
virtual void AddVolumeContextMenu(BMenu*);
virtual void AddDropContextMenu(BMenu*);
virtual void AddTrashContextMenu(BMenu*);
virtual void AddFileContextMenus(BMenu*);
virtual void AddWindowContextMenus(BMenu*);
virtual void AddVolumeContextMenus(BMenu*);
virtual void AddDropContextMenus(BMenu*);
virtual void AddTrashContextMenus(BMenu*);
virtual void DetachSubmenus();
virtual void RepopulateMenus();
void PopulateArrangeByMenu(BMenu*);
virtual void SetCutItem(BMenu*);
virtual void SetCopyItem(BMenu*);
virtual void SetPasteItem(BMenu*);
virtual void SetArrangeMenu(BMenu*);
virtual void SetCloseItem(BMenu*);
virtual void SetupNavigationMenu(const entry_ref*, BMenu*);
virtual void SetupMoveCopyMenus(const entry_ref*, BMenu*);
virtual void SetupNavigationMenu(BMenu*, const entry_ref*);
virtual void SetupMoveCopyMenus(BMenu*, const entry_ref*);
virtual void PopulateMoveCopyNavMenu(BNavMenu*, uint32,
const entry_ref*, bool);
virtual void SetupOpenWithMenu(BMenu*);
virtual void SetupOpenWithMenu(BMenu*, const entry_ref* ref);
virtual void SetupNewTemplatesMenu(BMenu*, MenuContext context);
virtual void SetupEditQueryItem(BMenu*);
virtual void SetupEditQueryItem(BMenu*, const entry_ref* ref);
virtual void SetupDiskMenu(BMenu*);
virtual void BuildAddOnsMenu(BMenu*);
void BuildMimeTypeList(BStringList& mimeTypes);
enum UpdateMenuContext {
kMenuBarContext,
kPosePopUpContext,
kWindowPopUpContext
};
virtual void UpdateMenu(BMenu* menu, UpdateMenuContext context);
virtual void UpdateMenu(BMenu* menu, MenuContext context,
const entry_ref* ref = NULL);
virtual void UpdateFileMenu(BMenu* menu);
virtual void UpdatePoseContextMenu(BMenu* menu, const entry_ref* ref);
virtual void UpdateFileMenuOrPoseContextMenu(BMenu* menu, MenuContext context,
const entry_ref* ref = NULL);
virtual void UpdateWindowMenu(BMenu* menu);
virtual void UpdateWindowContextMenu(BMenu* menu);
virtual void UpdateWindowMenuOrWindowContextMenu(BMenu* menu, MenuContext context);
BMenu* AddMimeMenu(const BMimeType& mimeType, bool isSuperType,
BMenu* menu, int32 start);
@@ -270,6 +289,12 @@ protected:
uint32 fOpenFlags;
bool fUsesLayout;
bool ShouldHaveNavigationMenu(const entry_ref* = NULL);
bool ShouldHaveOpenWithMenu(const entry_ref* = NULL);
bool ShouldHaveEditQueryItem(const entry_ref* = NULL);
bool ShouldHaveMoveCopyMenus(const entry_ref* = NULL);
bool ShouldHaveNewFolderItem();
BGroupLayout* fRootLayout;
BGroupView* fMenuContainer;
BGridView* fPoseContainer;
@@ -277,8 +302,9 @@ protected:
BGroupView* fVScrollBarContainer;
BGroupView* fCountContainer;
TShortcuts* fShortcuts;
BPopUpMenu* fContextMenu;
BPopUpMenu* fFileContextMenu;
BPopUpMenu* fPoseContextMenu;
BPopUpMenu* fWindowContextMenu;
BPopUpMenu* fDropContextMenu;
BPopUpMenu* fVolumeContextMenu;
@@ -288,7 +314,9 @@ protected:
BMenuItem* fCopyToItem;
BMenuItem* fCreateLinkItem;
BMenuItem* fOpenWithItem;
BMenuItem* fEditQueryItem;
ModelMenuItem* fNavigationItem;
BMenuItem* fNewTemplatesItem;
BMenuBar* fMenuBar;
DraggableContainerIcon* fDraggableIcon;
BNavigator* fNavigator;
@@ -296,7 +324,7 @@ protected:
BMenu* fAttrMenu;
BMenu* fWindowMenu;
BMenu* fFileMenu;
BMenu* fArrangeByMenu;
BMenuItem* fArrangeByItem;
SelectionWindow* fSelectionWindow;
@@ -391,6 +419,13 @@ BContainerWindow::PoseView() const
}
inline TShortcuts*
BContainerWindow::Shortcuts() const
{
return fShortcuts;
}
inline void
BContainerWindow::SetupDiskMenu(BMenu*)
{
+46 -101
View File
@@ -64,6 +64,7 @@ All rights reserved.
#include "KeyInfos.h"
#include "MountMenu.h"
#include "PoseView.h"
#include "Shortcuts.h"
#include "TemplatesMenu.h"
#include "Tracker.h"
@@ -194,21 +195,17 @@ BDeskWindow::BDeskWindow(LockingList<BWindow>* windowList, uint32 openFlags)
fNodeRef(NULL),
fShortcutsSettings(NULL)
{
// Add icon view switching shortcuts. These are displayed in the context
// menu, although they obviously don't work from those menu items.
BMessage* message = new BMessage(kIconMode);
AddShortcut('1', B_COMMAND_KEY, message, PoseView());
message = new BMessage(kMiniIconMode);
AddShortcut('2', B_COMMAND_KEY, message, PoseView());
message = new BMessage(kIconMode);
message->AddInt32("scale", 1);
AddShortcut('+', B_COMMAND_KEY, message, PoseView());
message = new BMessage(kIconMode);
message->AddInt32("scale", 0);
AddShortcut('-', B_COMMAND_KEY, message, PoseView());
// create pose view
BDirectory deskDir;
if (FSGetDeskDir(&deskDir) == B_OK) {
BEntry entry;
deskDir.GetEntry(&entry);
Model* model = new Model(&entry, true);
if (model->InitCheck() == B_OK)
CreatePoseView(model);
else
delete model;
}
}
@@ -254,6 +251,40 @@ BDeskWindow::Init(const BMessage*)
if (fDeskShelf != NULL)
fDeskShelf->SetDisplaysZombies(true);
}
// Add icon view switching shortcuts. These are displayed in the context
// menu, although they obviously don't work from those menu items.
BMessage* message = new BMessage(kIconMode);
AddShortcut('1', B_COMMAND_KEY, message, PoseView());
message = new BMessage(kMiniIconMode);
AddShortcut('2', B_COMMAND_KEY, message, PoseView());
message = new BMessage(kIconMode);
message->AddInt32("scale", 1);
AddShortcut('+', B_COMMAND_KEY, message, PoseView());
message = new BMessage(kIconMode);
message->AddInt32("scale", 0);
AddShortcut('-', B_COMMAND_KEY, message, PoseView());
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);
PostMessage(&message, PoseView());
}
}
}
@@ -435,92 +466,6 @@ BDeskWindow::CreatePoseView(Model* model)
}
void
BDeskWindow::AddWindowContextMenus(BMenu* menu)
{
TemplatesMenu* tempateMenu = new TemplatesMenu(PoseView(),
B_TRANSLATE("New"));
menu->AddItem(tempateMenu);
tempateMenu->SetTargetForItems(PoseView());
menu->AddSeparatorItem();
BMenu* iconSizeMenu = new BMenu(B_TRANSLATE("Icon view"));
BMenuItem* item;
static const uint32 kIconSizes[] = { 32, 40, 48, 64, 96, 128 };
BMessage* message;
for (uint32 i = 0; i < sizeof(kIconSizes) / sizeof(uint32); ++i) {
uint32 iconSize = kIconSizes[i];
message = new BMessage(kIconMode);
message->AddInt32("size", iconSize);
BString label;
label.SetToFormat(B_TRANSLATE_COMMENT("%" B_PRId32" × %" B_PRId32,
"The '×' is the Unicode multiplication sign U+00D7"),
iconSize, iconSize);
item = new BMenuItem(label, message);
item->SetMarked(PoseView()->IconSizeInt() == iconSize);
item->SetTarget(PoseView());
iconSizeMenu->AddItem(item);
}
iconSizeMenu->AddSeparatorItem();
message = new BMessage(kIconMode);
message->AddInt32("scale", 0);
item = new BMenuItem(B_TRANSLATE("Decrease size"), message, '-');
item->SetTarget(PoseView());
iconSizeMenu->AddItem(item);
message = new BMessage(kIconMode);
message->AddInt32("scale", 1);
item = new BMenuItem(B_TRANSLATE("Increase size"), message, '+');
item->SetTarget(PoseView());
iconSizeMenu->AddItem(item);
// A sub menu where the super item can be invoked.
menu->AddItem(iconSizeMenu);
iconSizeMenu->Superitem()->SetShortcut('1', B_COMMAND_KEY);
iconSizeMenu->Superitem()->SetMessage(new BMessage(kIconMode));
iconSizeMenu->Superitem()->SetTarget(PoseView());
iconSizeMenu->Superitem()->SetMarked(PoseView()->ViewMode() == kIconMode);
item = new BMenuItem(B_TRANSLATE("Mini icon view"),
new BMessage(kMiniIconMode), '2');
item->SetMarked(PoseView()->ViewMode() == kMiniIconMode);
menu->AddItem(item);
menu->AddSeparatorItem();
#ifdef CUT_COPY_PASTE_IN_CONTEXT_MENU
BMenuItem* pasteItem = new BMenuItem(B_TRANSLATE("Paste"),
new BMessage(B_PASTE), 'V');
menu->AddItem(pasteItem);
menu->AddSeparatorItem();
#endif
menu->AddItem(new BMenuItem(B_TRANSLATE("Clean up"),
new BMessage(kCleanup), 'K'));
menu->AddItem(new BMenuItem(B_TRANSLATE("Select" B_UTF8_ELLIPSIS),
new BMessage(kShowSelectionWindow), 'A', B_SHIFT_KEY));
menu->AddItem(new BMenuItem(B_TRANSLATE("Select all"),
new BMessage(B_SELECT_ALL), 'A'));
menu->AddSeparatorItem();
menu->AddItem(new MountMenu(B_TRANSLATE("Mount")));
menu->AddSeparatorItem();
menu->AddItem(new BMenu(B_TRANSLATE("Add-ons")));
// target items as needed
menu->SetTargetForItems(PoseView());
#ifdef CUT_COPY_PASTE_IN_CONTEXT_MENU
pasteItem->SetTarget(this);
#endif
}
void
BDeskWindow::WorkspaceActivated(int32 workspace, bool state)
{
-1
View File
@@ -71,7 +71,6 @@ public:
void SaveDesktopPoseLocations();
protected:
virtual void AddWindowContextMenus(BMenu*);
virtual BPoseView* NewPoseView(Model*, uint32);
virtual void WorkspaceActivated(int32, bool);
+2 -2
View File
@@ -296,7 +296,7 @@ BFilePanel::SetPanelDirectory(const entry_ref* ref)
if (!lock)
return;
static_cast<TFilePanel*>(fWindow)->SetTo(ref);
static_cast<TFilePanel*>(fWindow)->SwitchDirectory(ref);
}
@@ -312,7 +312,7 @@ BFilePanel::SetPanelDirectory(const char* path)
if (!lock)
return;
static_cast<TFilePanel*>(fWindow)->SetTo(&ref);
static_cast<TFilePanel*>(fWindow)->SwitchDirectory(&ref);
}
+309 -374
View File
@@ -77,6 +77,7 @@ All rights reserved.
#include "IconMenuItem.h"
#include "MimeTypes.h"
#include "NavMenu.h"
#include "Shortcuts.h"
#include "Tracker.h"
#include "Utilities.h"
@@ -114,11 +115,7 @@ key_down_filter(BMessage* message, BHandler** handler, BMessageFilter* filter)
if (filter == NULL)
return B_DISPATCH_MESSAGE;
BLooper* looper = filter->Looper();
if (looper == NULL)
return B_DISPATCH_MESSAGE;
TFilePanel* panel = dynamic_cast<TFilePanel*>(looper);
TFilePanel* panel = dynamic_cast<TFilePanel*>(filter->Looper());
if (panel == NULL || panel->TrackingMenu())
return B_DISPATCH_MESSAGE;
@@ -135,11 +132,11 @@ key_down_filter(BMessage* message, BHandler** handler, BMessageFilter* filter)
if ((modifiers & B_COMMAND_KEY) != 0) {
switch (key) {
case B_UP_ARROW:
looper->PostMessage(kOpenParentDir);
BMessenger(panel).SendMessage(kOpenParentDir);
return B_SKIP_MESSAGE;
case 'w':
looper->PostMessage(kCancelButton);
BMessenger(panel).SendMessage(kCancelButton);
return B_SKIP_MESSAGE;
default:
@@ -151,9 +148,9 @@ key_down_filter(BMessage* message, BHandler** handler, BMessageFilter* filter)
if (view->ActivePose() != NULL)
view->CommitActivePose(false);
else if (view->IsTypeAheadFiltering())
looper->PostMessage(B_CANCEL, *handler);
BMessenger(panel).SendMessage(B_CANCEL, *handler);
else
looper->PostMessage(kCancelButton);
BMessenger(panel).SendMessage(kCancelButton);
return B_SKIP_MESSAGE;
}
@@ -183,6 +180,7 @@ TFilePanel::TFilePanel(file_panel_mode mode, BMessenger* target, const BEntry* s
fClientObject(NULL),
fSelectionIterator(0),
fMessage(NULL),
fFavoritesMenu(NULL),
fHideWhenDone(hideWhenDone),
fIsTrackingMenu(false),
fDefaultStateRestored(false)
@@ -212,8 +210,10 @@ TFilePanel::TFilePanel(file_panel_mode mode, BMessenger* target, const BEntry* s
else
fMessage = new BMessage(B_REFS_RECEIVED);
gLocalizedNamePreferred
= BLocaleRoster::Default()->IsFilesystemTranslationPreferred();
// no new template menu in file panel
fNewTemplatesItem = NULL;
gLocalizedNamePreferred = BLocaleRoster::Default()->IsFilesystemTranslationPreferred();
// check for legal starting directory
Model* model = new Model();
@@ -357,21 +357,18 @@ TFilePanel::MessageDropFilter(BMessage* message, BHandler**, BMessageFilter* fil
entry.GetRef(&ref);
panel->fTaskLoop->RunLater(NewMemberFunctionObjectWithResult
(&TFilePanel::SelectChildInParent, panel,
const_cast<const entry_ref*>(&ref),
const_cast<const node_ref*>(&child)),
ref == *panel->TargetModel()->EntryRef() ? 0 : 100000, 200000,
5000000);
// if the target directory is already current, we won't
// delay the initial selection try
// don't delay the initial selection try if the target directory is already current
panel->fTaskLoop->RunLater(
NewMemberFunctionObjectWithResult(&TFilePanel::SelectChildInParent, panel,
const_cast<const entry_ref*>(&ref), const_cast<const node_ref*>(&child)),
ref == *panel->TargetModel()->EntryRef() ? 0 : 100000, 200000, 5000000);
// also set the save name to the dragged in entry
if (panel->IsSavePanel())
panel->SetSaveText(path.Leaf());
}
panel->SetTo(&ref);
panel->SwitchDirectory(&ref);
return B_SKIP_MESSAGE;
}
@@ -412,7 +409,7 @@ TFilePanel::FSFilter(BMessage* message, BHandler**, BMessageFilter* filter)
// but not wind title
if (*(panel->TargetModel()->NodeRef()) == itemNode) {
panel->TargetModel()->UpdateEntryRef(&dirNode, name);
panel->SetTo(panel->TargetModel()->EntryRef());
panel->SwitchDirectory(panel->TargetModel()->EntryRef());
return B_SKIP_MESSAGE;
}
break;
@@ -439,9 +436,7 @@ TFilePanel::FSFilter(BMessage* message, BHandler**, BMessageFilter* filter)
root.GetEntry(&entry);
entry.GetRef(&ref);
panel->SwitchDirToDesktopIfNeeded(ref);
panel->SetTo(&ref);
panel->SwitchDirectory(&ref);
return B_SKIP_MESSAGE;
}
break;
@@ -544,25 +539,37 @@ TFilePanel::SetRefFilter(BRefFilter* filter)
void
TFilePanel::SetTo(const entry_ref* ref)
TFilePanel::SwitchDirectory(const entry_ref* ref)
{
if (ref == NULL)
return;
entry_ref setToRef(*ref);
bool isDesktop = SwitchDirToDesktopIfNeeded(setToRef);
BEntry entry(&setToRef);
if (entry.InitCheck() != B_OK || !entry.IsDirectory())
BEntry entry(&setToRef, true);
if (entry.InitCheck() != B_OK)
return;
PoseView()->SetIsDesktop(isDesktop);
PoseView()->SwitchDir(&setToRef);
SwitchDirMenuTo(&setToRef);
_inherited::SwitchDirectory(&setToRef);
AddShortcut('H', B_COMMAND_KEY, new BMessage(kSwitchToHome));
// our shortcut got possibly removed because the home
// menu item got removed - we shouldn't really have to do
// this - this is a workaround for a kit bug.
// update the menu field
for (int32 index = fDirMenu->CountItems() - 1; index >= 0; index--)
delete fDirMenu->RemoveItem(index);
fDirMenuField->MenuBar()->RemoveItem((int32)0);
fDirMenu->Populate(&entry, 0, true, true, false, true);
ModelMenuItem* item = dynamic_cast<ModelMenuItem*>(fDirMenuField->MenuBar()->ItemAt(0));
ASSERT(item);
// set dir menu to the new directory
item->SetEntry(&entry);
}
@@ -711,8 +718,7 @@ TFilePanel::Init(const BMessage*)
fDirMenuField->MenuBar()->SetMaxContentWidth(rect.Width() - 26.0f);
// Make room for the icon
fDirMenu = new BDirMenu(fDirMenuField->MenuBar(),
this, kSwitchDirectory, "refs");
fDirMenu = new BDirMenu(fDirMenuField->MenuBar(), this, kSwitchDirectory, "refs");
BEntry entry(TargetModel()->EntryRef());
if (entry.InitCheck() == B_OK)
@@ -786,20 +792,18 @@ TFilePanel::Init(const BMessage*)
else
fBackView->AddChild(fPoseContainer);
fShortcuts = new TShortcuts(this);
AddShortcut('W', B_COMMAND_KEY, new BMessage(kCancelButton));
AddShortcut('H', B_COMMAND_KEY, new BMessage(kSwitchToHome));
AddShortcut('A', B_COMMAND_KEY | B_SHIFT_KEY,
new BMessage(kShowSelectionWindow));
AddShortcut('A', B_COMMAND_KEY | B_SHIFT_KEY, new BMessage(kShowSelectionWindow));
AddShortcut('A', B_COMMAND_KEY, new BMessage(B_SELECT_ALL), this);
AddShortcut('S', B_COMMAND_KEY, new BMessage(kInvertSelection),
PoseView());
AddShortcut('S', B_COMMAND_KEY, new BMessage(kInvertSelection), PoseView());
AddShortcut('Y', B_COMMAND_KEY, new BMessage(kResizeToFit), PoseView());
AddShortcut(B_DOWN_ARROW, B_COMMAND_KEY, new BMessage(kOpenDir));
AddShortcut(B_DOWN_ARROW, B_COMMAND_KEY | B_OPTION_KEY,
new BMessage(kOpenDir));
AddShortcut(B_DOWN_ARROW, B_COMMAND_KEY | B_OPTION_KEY, new BMessage(kOpenDir));
AddShortcut(B_UP_ARROW, B_COMMAND_KEY, new BMessage(kOpenParentDir));
AddShortcut(B_UP_ARROW, B_COMMAND_KEY | B_OPTION_KEY,
new BMessage(kOpenParentDir));
AddShortcut(B_UP_ARROW, B_COMMAND_KEY | B_OPTION_KEY, new BMessage(kOpenParentDir));
if (!fIsSavePanel && (fNodeFlavors & B_DIRECTORY_NODE) == 0)
default_button->SetEnabled(false);
@@ -808,54 +812,10 @@ TFilePanel::Init(const BMessage*)
RestoreState();
AddMenus();
if (ShouldAddMenus())
AddMenus();
AddContextMenus();
FavoritesMenu* favorites = new FavoritesMenu(B_TRANSLATE("Favorites"),
new BMessage(kSwitchDirectory), new BMessage(B_REFS_RECEIVED),
BMessenger(this), IsSavePanel(), fPoseView->RefFilter());
favorites->AddItem(new BMenuItem(B_TRANSLATE("Add current folder"),
new BMessage(kAddCurrentDir)));
favorites->AddItem(new BMenuItem(
B_TRANSLATE("Edit favorites" B_UTF8_ELLIPSIS),
new BMessage(kEditFavorites)));
fMenuBar->AddItem(favorites);
// configure menus
BMenuItem* item = fMenuBar->FindItem(B_TRANSLATE("Window"));
if (item) {
fMenuBar->RemoveItem(item);
delete item;
}
item = fMenuBar->FindItem(B_TRANSLATE("File"));
if (item) {
BMenu* menu = item->Submenu();
if (menu) {
item = menu->FindItem(kOpenSelection);
if (item && menu->RemoveItem(item))
delete item;
// remove add-ons menu, identifier menu, separator
item = menu->FindItem(B_TRANSLATE("Add-ons"));
if (item) {
int32 index = menu->IndexOf(item);
delete menu->RemoveItem(index);
delete menu->RemoveItem(--index);
delete menu->RemoveItem(--index);
}
// remove separator
item = menu->FindItem(B_CUT);
if (item) {
item = menu->ItemAt(menu->IndexOf(item)-1);
if (item && menu->RemoveItem(item))
delete item;
}
}
}
PoseView()->ScrollTo(B_ORIGIN);
PoseView()->UpdateScrollRange();
PoseView()->ScrollTo(B_ORIGIN);
@@ -886,6 +846,67 @@ TFilePanel::Init(const BMessage*)
}
void
TFilePanel::AddMenus()
{
// File
fFileMenu = new BMenu(B_TRANSLATE("File"));
AddFileMenu(fFileMenu);
fMenuBar->AddItem(fFileMenu);
// Favorites
fFavoritesMenu = new FavoritesMenu(B_TRANSLATE("Favorites"), new BMessage(kSwitchDirectory),
new BMessage(B_REFS_RECEIVED), BMessenger(this), IsSavePanel(), Filter());
AddFavoritesMenu(fFavoritesMenu);
fMenuBar->AddItem(fFavoritesMenu);
}
void
TFilePanel::AddFileMenu(BMenu* menu)
{
menu->AddItem(Shortcuts()->NewFolderItem());
menu->AddItem(new BSeparatorItem());
menu->AddItem(Shortcuts()->GetInfoItem());
menu->AddItem(Shortcuts()->EditNameItem());
if (TargetModel()->IsTrash() || TargetModel()->InTrash()) {
menu->AddItem(Shortcuts()->DeleteItem());
menu->AddItem(Shortcuts()->RestoreItem());
} else {
menu->AddItem(Shortcuts()->DuplicateItem());
menu->AddItem(Shortcuts()->MoveToTrashItem());
}
if (!TargetModel()->IsPrintersDir() || TargetModel()->IsRoot() || TargetModel()->IsTrash()
|| TargetModel()->InTrash()) {
menu->AddSeparatorItem();
menu->AddItem(Shortcuts()->CutItem());
menu->AddItem(Shortcuts()->CopyItem());
menu->AddItem(Shortcuts()->PasteItem());
}
}
void
TFilePanel::AddWindowMenu(BMenu* menu)
{
// no window menu on file panel
}
void
TFilePanel::AddFavoritesMenu(BMenu* menu)
{
const char* name = B_TRANSLATE("Add current folder");
menu->AddItem(new BMenuItem(name, new BMessage(kAddCurrentDir)));
name = B_TRANSLATE("Edit favorites" B_UTF8_ELLIPSIS);
menu->AddItem(new BMenuItem(name, new BMessage(kEditFavorites)));
}
void
TFilePanel::RestoreState()
{
@@ -961,103 +982,71 @@ TFilePanel::RestoreWindowState(const BMessage &message)
void
TFilePanel::AddFileContextMenus(BMenu* menu)
TFilePanel::AddPoseContextMenu(BMenu* menu)
{
menu->AddItem(new BMenuItem(B_TRANSLATE("Get info"),
new BMessage(kGetInfo), 'I'));
menu->AddItem(new BMenuItem(B_TRANSLATE("Edit name"),
new BMessage(kEditItem), 'E'));
menu->AddItem(new BMenuItem(B_TRANSLATE("Duplicate"),
new BMessage(kDuplicateSelection), 'D'));
menu->AddItem(new BMenuItem(B_TRANSLATE("Move to Trash"),
new BMessage(kMoveSelectionToTrash), 'T'));
menu->AddItem(Shortcuts()->GetInfoItem());
menu->AddItem(Shortcuts()->EditNameItem());
if (TargetModel()->InTrash()) {
menu->AddItem(Shortcuts()->DeleteItem());
menu->AddItem(Shortcuts()->RestoreItem());
} else {
menu->AddItem(Shortcuts()->DuplicateItem());
menu->AddItem(Shortcuts()->MoveToTrashItem());
}
menu->AddSeparatorItem();
BMenuItem* cutItem = new BMenuItem(B_TRANSLATE("Cut"),
new BMessage(B_CUT), 'X');
menu->AddItem(cutItem);
BMenuItem* copyItem = new BMenuItem(B_TRANSLATE("Copy"),
new BMessage(B_COPY), 'C');
menu->AddItem(copyItem);
#if CUT_COPY_PASTE_IN_CONTEXT_MENU
BMenuItem* pasteItem = new BMenuItem(B_TRANSLATE("Paste"),
new BMessage(B_PASTE), 'V');
menu->AddItem(pasteItem);
#endif
menu->SetTargetForItems(PoseView());
cutItem->SetTarget(this);
copyItem->SetTarget(this);
#if CUT_COPY_PASTE_IN_CONTEXT_MENU
pasteItem->SetTarget(this);
menu->AddItem(Shortcuts()->CutItem());
menu->AddItem(Shortcuts()->CopyItem());
#ifdef CUT_COPY_PASTE_IN_CONTEXT_MENU
menu->AddItem(Shortcuts()->PasteItem());
#endif
}
void
TFilePanel::AddVolumeContextMenus(BMenu* menu)
TFilePanel::AddVolumeContextMenu(BMenu* menu)
{
menu->AddItem(new BMenuItem(B_TRANSLATE("Open"),
new BMessage(kOpenSelection), 'O'));
menu->AddItem(new BMenuItem(B_TRANSLATE("Get info"),
new BMessage(kGetInfo), 'I'));
menu->AddItem(new BMenuItem(B_TRANSLATE("Edit name"),
new BMessage(kEditItem), 'E'));
menu->AddItem(Shortcuts()->OpenItem());
menu->AddItem(Shortcuts()->GetInfoItem());
menu->AddItem(Shortcuts()->EditNameItem());
#if CUT_COPY_PASTE_IN_CONTEXT_MENU
#ifdef CUT_COPY_PASTE_IN_CONTEXT_MENU
menu->AddSeparatorItem();
BMenuItem* pasteItem = new BMenuItem(B_TRANSLATE("Paste"),
new BMessage(B_PASTE), 'V');
#endif
menu->SetTargetForItems(PoseView());
#if CUT_COPY_PASTE_IN_CONTEXT_MENU
pasteItem->SetTarget(this);
menu->AddItem(Shortcuts()->PasteItem());
#endif
}
void
TFilePanel::AddWindowContextMenus(BMenu* menu)
TFilePanel::AddWindowContextMenu(BMenu* menu)
{
BMenuItem* item = new BMenuItem(B_TRANSLATE("New folder"),
new BMessage(kNewFolder), 'N');
item->SetTarget(PoseView());
menu->AddItem(item);
menu->AddSeparatorItem();
menu->AddItem(Shortcuts()->NewFolderItem());
menu->AddItem(new BSeparatorItem());
#if CUT_COPY_PASTE_IN_CONTEXT_MENU
item = new BMenuItem(B_TRANSLATE("Paste"), new BMessage(B_PASTE), 'V');
item->SetTarget(this);
menu->AddItem(item);
#ifdef CUT_COPY_PASTE_IN_CONTEXT_MENU
menu->AddItem(Shortcuts()->PasteItem());
menu->AddSeparatorItem();
#endif
item = new BMenuItem(B_TRANSLATE("Select" B_UTF8_ELLIPSIS),
new BMessage(kShowSelectionWindow), 'A', B_SHIFT_KEY);
item->SetTarget(PoseView());
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Select all"),
new BMessage(B_SELECT_ALL), 'A');
item->SetTarget(this);
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Invert selection"),
new BMessage(kInvertSelection), 'S');
item->SetTarget(PoseView());
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Go to parent"),
new BMessage(kOpenParentDir), B_UP_ARROW);
item->SetTarget(this);
menu->AddItem(item);
menu->AddItem(Shortcuts()->SelectItem());
menu->AddItem(Shortcuts()->SelectAllItem());
menu->AddItem(Shortcuts()->InvertSelectionItem());
menu->AddItem(Shortcuts()->OpenParentItem());
}
void
TFilePanel::AddDropContextMenus(BMenu*)
TFilePanel::AddTrashContextMenu(BMenu* menu)
{
// use default window context menu on Trash
AddWindowContextMenu(menu);
}
void
TFilePanel::AddDropContextMenu(BMenu*)
{
// do nothing here so drop context menu doesn't get added
}
@@ -1073,17 +1062,7 @@ TFilePanel::MenusBeginning()
PoseView()->CommitActivePose();
}
EnableNamedMenuItem(fMenuBar, kNewFolder, !TargetModel()->IsRoot()
&& !PoseView()->TargetVolumeIsReadOnly());
EnableNamedMenuItem(fMenuBar, kDuplicateSelection,
PoseView()->CanMoveToTrashOrDuplicate());
EnableNamedMenuItem(fMenuBar, kMoveSelectionToTrash,
PoseView()->CanMoveToTrashOrDuplicate());
EnableNamedMenuItem(fMenuBar, kEditItem, PoseView()->CanEditName());
SetCutItem(fMenuBar);
SetCopyItem(fMenuBar);
SetPasteItem(fMenuBar);
UpdateMenu(fFileMenu, kFileMenuContext);
fIsTrackingMenu = true;
}
@@ -1097,64 +1076,74 @@ TFilePanel::MenusEnded()
void
TFilePanel::ShowContextMenu(BPoint where, const entry_ref* ref)
TFilePanel::DetachSubmenus()
{
ASSERT(IsLocked());
BPoint global(where);
PoseView()->ConvertToScreen(&global);
PoseView()->CommitActivePose();
if (ref != NULL) {
// clicked on a pose, show file or volume context menu
Model model(ref);
if (model.InitCheck() != B_OK)
return; // bail out, do not show context menu
if (TargetModel()->IsRoot() || model.IsVolume()) {
// Volume context menu
fContextMenu = fVolumeContextMenu;
EnableNamedMenuItem(fContextMenu, kOpenSelection, true);
EnableNamedMenuItem(fContextMenu, kEditItem,
PoseView()->CanEditName());
SetPasteItem(fContextMenu);
} else {
// File context menu
fContextMenu = fFileContextMenu;
EnableNamedMenuItem(fContextMenu, kEditItem,
PoseView()->CanEditName());
EnableNamedMenuItem(fContextMenu, kDuplicateSelection,
PoseView()->CanMoveToTrashOrDuplicate());
EnableNamedMenuItem(fContextMenu, kMoveSelectionToTrash,
PoseView()->CanMoveToTrashOrDuplicate());
SetCutItem(fContextMenu);
SetCopyItem(fContextMenu);
SetPasteItem(fContextMenu);
}
} else {
// Window context menu
fContextMenu = fWindowContextMenu;
EnableNamedMenuItem(fContextMenu, kNewFolder,
!TargetModel()->IsRoot()
&& !PoseView()->TargetVolumeIsReadOnly());
EnableNamedMenuItem(fContextMenu, kOpenParentDir,
!TargetModel()->IsRoot());
SetPasteItem(fContextMenu);
}
// context menu invalid or popup window is already open
if (fContextMenu == NULL || fContextMenu->Window() != NULL)
return;
fContextMenu->Go(global, true, true, true);
fContextMenu = NULL;
// no submenus to detatch in file panel
}
void
TFilePanel::SetupNavigationMenu(const entry_ref*, BMenu*)
TFilePanel::UpdateFileMenu(BMenu*)
{
// nothing more to do
}
void
TFilePanel::UpdateFileMenuOrPoseContextMenu(BMenu*, MenuContext, const entry_ref*)
{
// nothing more to do
}
void
TFilePanel::UpdateWindowMenu(BMenu*)
{
// no window menu on file panel
}
void
TFilePanel::UpdateWindowContextMenu(BMenu*)
{
// nothing more to do
}
void
TFilePanel::UpdateWindowMenuOrWindowContextMenu(BMenu*, MenuContext)
{
// nothing more to do
}
void
TFilePanel::RepopulateMenus()
{
if (fMenuBar != NULL && fFileMenu != NULL) {
fMenuBar->RemoveItem(fFileMenu);
delete fFileMenu;
if (ShouldAddMenus()) {
fFileMenu = new BMenu(B_TRANSLATE("File"));
TFilePanel::AddFileMenu(fFileMenu);
fMenuBar->AddItem(fFileMenu, 0);
}
}
delete fPoseContextMenu;
fPoseContextMenu = new BPopUpMenu("PoseContext", false, false);
fPoseContextMenu->SetFont(be_plain_font);
TFilePanel::AddPoseContextMenu(fPoseContextMenu);
delete fWindowContextMenu;
fWindowContextMenu = new BPopUpMenu("WindowContext", false, false);
fWindowContextMenu->SetFont(be_plain_font);
TFilePanel::AddWindowContextMenu(fWindowContextMenu);
}
void
TFilePanel::SetupNavigationMenu(BMenu*, const entry_ref*)
{
// do nothing here so nav menu doesn't get added
}
@@ -1230,84 +1219,77 @@ TFilePanel::MessageReceived(BMessage* message)
switch (message->what) {
case B_REFS_RECEIVED:
{
// item was double clicked in file panel (PoseView) or from the favorites menu
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);
if (message->FindRef("refs", &ref) != B_OK)
break;
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 if it comes from the file
// panel; all we have to do is see if the button is enabled.
// In other cases, however, we can't rely on that. So first check for
// TrackerViewToken in the message to see if it's coming from the pose view
if (message->HasMessenger("TrackerViewToken")) {
BButton* button = dynamic_cast<BButton*>(FindView("default button"));
if (button == NULL || !button->IsEnabled())
break;
}
BEntry entry(&ref, true);
if (entry.InitCheck() != B_OK)
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);
}
// Double-click on dir or link-to-dir ALWAYS opens the dir.
// If more than one dir is selected the first one is opened.
if (entry.IsDirectory()) {
SwitchDirectory(&ref);
} else {
// Otherwise, we have a file or a link to a file.
// AdjustButton has already tested the flavor if it comes from the file
// panel; all we have to do is see if the button is enabled.
// In other cases, however, we can't rely on that. So first check for
// TrackerViewToken in the message to see if it's coming from the pose view
if (message->HasMessenger("TrackerViewToken")) {
BButton* button = dynamic_cast<BButton*>(FindView("default button"));
if (button == NULL || !button->IsEnabled())
break;
}
if (IsSavePanel()) {
int32 count = 0;
type_code type;
message->GetInfo("refs", &type, &count);
// Don't allow saves of multiple files
if (count > 1) {
const char* sorry
= B_TRANSLATE("Sorry, saving more than one item is not allowed.");
ShowCenteredAlert(sorry, 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);
}
if (message->FindRef("refs", &ref) != B_OK)
break;
SwitchDirectory(&ref);
break;
}
@@ -1320,7 +1302,7 @@ TFilePanel::MessageReceived(BMessage* message)
break;
}
SetTo(&ref);
SwitchDirectory(&ref);
break;
}
@@ -1387,8 +1369,7 @@ TFilePanel::MessageReceived(BMessage* message)
if (fIsSavePanel) {
if (PoseView()->IsFocus()
&& PoseView()->CountSelected() == 1) {
Model* model = (PoseView()->SelectionList()->
FirstItem())->TargetModel();
Model* model = (PoseView()->SelectionList()->FirstItem())->TargetModel();
if (model->ResolveIfLink()->IsDirectory()) {
PoseView()->CommitActivePose();
PoseView()->OpenSelection();
@@ -1404,20 +1385,21 @@ TFilePanel::MessageReceived(BMessage* message)
case B_OBSERVER_NOTICE_CHANGE:
{
int32 observerWhat;
if (message->FindInt32("be:observe_change_what", &observerWhat)
== B_OK) {
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);
bool desktopIsRoot;
if (message->FindBool("DesktopFilePanelRoot", &desktopIsRoot) == B_OK
&& TrackerSettings().DesktopFilePanelRoot() != desktopIsRoot) {
TrackerSettings().SetDesktopFilePanelRoot(desktopIsRoot);
SwitchDirectory(TargetModel()->EntryRef());
}
SetTo(TargetModel()->EntryRef());
break;
}
default:
break;
}
}
break;
@@ -1441,7 +1423,7 @@ TFilePanel::OpenDirectory()
if (model->ResolveIfLink()->IsDirectory()) {
BMessage message(B_REFS_RECEIVED);
message.AddRef("refs", model->EntryRef());
PostMessage(&message);
BMessenger(this).SendMessage(&message);
}
}
@@ -1449,52 +1431,29 @@ TFilePanel::OpenDirectory()
void
TFilePanel::OpenParent()
{
if (!CanOpenParent())
return;
BEntry entry(TargetModel()->EntryRef());
Model oldModel(*PoseView()->TargetModel());
const node_ref* oldNode = oldModel.NodeRef();
BEntry parentEntry;
BDirectory dir;
Model oldModel(*PoseView()->TargetModel());
BEntry entry(oldModel.EntryRef());
if (entry.InitCheck() == B_OK
&& entry.GetParent(&dir) == B_OK
&& dir.GetEntry(&parentEntry) == B_OK
&& entry != parentEntry) {
entry_ref ref;
parentEntry.GetRef(&ref);
PoseView()->SetIsDesktop(SwitchDirToDesktopIfNeeded(ref));
PoseView()->SwitchDir(&ref);
SwitchDirMenuTo(&ref);
// Make sure the child gets selected in the new view
// once it shows up.
fTaskLoop->RunLater(NewMemberFunctionObjectWithResult
(&TFilePanel::SelectChildInParent, this,
const_cast<const entry_ref*>(&ref),
oldModel.NodeRef()), 100000, 200000, 5000000);
}
}
bool
TFilePanel::CanOpenParent() const
{
if (TrackerSettings().DesktopFilePanelRoot()) {
// don't allow opening Desktop folder's parent
if (TargetModel()->IsDesktop())
return false;
if (TrackerSettings().DesktopFilePanelRoot() && FSIsRootDir(&entry)) {
// open parent on root, set to Desktop
BDirectory desktopDir;
if (FSGetDeskDir(&desktopDir) != B_OK || desktopDir.GetEntry(&parentEntry) != B_OK)
return;
} else if (FSGetParentVirtualDirectoryAware(entry, parentEntry) != B_OK) {
return;
}
// block on "/"
BEntry root("/");
node_ref rootRef;
root.GetNodeRef(&rootRef);
entry_ref setToRef;
parentEntry.GetRef(&setToRef);
const entry_ref* parent = &setToRef;
SwitchDirectory(parent);
return rootRef != *TargetModel()->NodeRef();
// Make sure the child gets selected in the new view once it shows up.
fTaskLoop->RunLater(
NewMemberFunctionObjectWithResult(&TFilePanel::SelectChildInParent, this, parent, oldNode),
100000, 200000, 5000000);
}
@@ -1510,19 +1469,17 @@ TFilePanel::SwitchDirToDesktopIfNeeded(entry_ref &ref)
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
if (FSIsDeskDir(&entry) || (!settings.ShowDisksIcon() && FSIsRootDir(&entry))) {
// navigated into desktop folder or hit "root" level, switch to Desktop
desktopDir.GetEntry(&entry);
entry.GetRef(&ref);
return true;
}
return FSIsDeskDir(&entry);
}
@@ -1723,25 +1680,6 @@ TFilePanel::HandleOpenButton()
}
void
TFilePanel::SwitchDirMenuTo(const entry_ref* ref)
{
BEntry entry(ref);
for (int32 index = fDirMenu->CountItems() - 1; index >= 0; index--)
delete fDirMenu->RemoveItem(index);
fDirMenuField->MenuBar()->RemoveItem((int32)0);
fDirMenu->Populate(&entry, 0, true, true, false, true);
ModelMenuItem* item = dynamic_cast<ModelMenuItem*>(
fDirMenuField->MenuBar()->ItemAt(0));
ASSERT(item != NULL);
if (item != NULL)
item->SetEntry(&entry);
}
void
TFilePanel::WindowActivated(bool active)
{
@@ -1897,9 +1835,9 @@ BFilePanelPoseView::ShowVolumes(bool visible, bool showShared)
AddRootPoses(true, showShared);
}
TFilePanel* filepanel = dynamic_cast<TFilePanel*>(Window());
if (filepanel != NULL && TargetModel() != NULL)
filepanel->SetTo(TargetModel()->EntryRef());
TFilePanel* panel = dynamic_cast<TFilePanel*>(Window());
if (panel != NULL && TargetModel() != NULL)
panel->SwitchDirectory(TargetModel()->EntryRef());
}
@@ -1912,8 +1850,7 @@ BFilePanelPoseView::AdaptToVolumeChange(BMessage* message)
message->FindBool("ShowDisksIcon", &showDisksIcon);
message->FindBool("MountVolumesOntoDesktop", &mountVolumesOnDesktop);
message->FindBool("MountSharedVolumesOntoDesktop",
&mountSharedVolumesOntoDesktop);
message->FindBool("MountSharedVolumesOntoDesktop", &mountSharedVolumesOntoDesktop);
BEntry entry("/");
Model model(&entry);
@@ -1931,8 +1868,7 @@ BFilePanelPoseView::AdaptToVolumeChange(BMessage* message)
monitorMsg.AddInt64("directory", model.EntryRef()->directory);
monitorMsg.AddString("name", model.EntryRef()->name);
TrackerSettings().SetShowDisksIcon(showDisksIcon);
if (Window() != NULL)
Window()->PostMessage(&monitorMsg, this);
Window()->PostMessage(&monitorMsg, this);
}
ShowVolumes(mountVolumesOnDesktop, mountSharedVolumesOntoDesktop);
@@ -1946,8 +1882,7 @@ BFilePanelPoseView::AdaptToDesktopIntegrationChange(BMessage* message)
bool mountSharedVolumesOntoDesktop = true;
message->FindBool("MountVolumesOntoDesktop", &mountVolumesOnDesktop);
message->FindBool("MountSharedVolumesOntoDesktop",
&mountSharedVolumesOntoDesktop);
message->FindBool("MountSharedVolumesOntoDesktop", &mountSharedVolumesOntoDesktop);
ShowVolumes(false, mountSharedVolumesOntoDesktop);
ShowVolumes(mountVolumesOnDesktop, mountSharedVolumesOntoDesktop);
+21 -9
View File
@@ -73,14 +73,13 @@ public:
virtual void MenusBeginning();
virtual void MenusEnded();
virtual void DispatchMessage(BMessage* message, BHandler* handler);
virtual void ShowContextMenu(BPoint, const entry_ref*);
void SetClientObject(BFilePanel*);
void SetRefFilter(BRefFilter*);
void SetNodeFlavors(uint32 nodeFlavors) { fNodeFlavors = nodeFlavors; }
void SetSaveText(const char* text);
void SetButtonLabel(file_panel_button, const char* text);
void SetTo(const entry_ref* ref);
virtual void SwitchDirectory(const entry_ref*);
virtual void SelectionChanged();
void HandleOpenButton();
void HandleSaveButton();
@@ -115,12 +114,26 @@ protected:
virtual void RestoreWindowState(const BMessage&);
virtual void RestoreState(const BMessage&);
virtual void AddFileContextMenus(BMenu*);
virtual void AddVolumeContextMenus(BMenu*);
virtual void AddWindowContextMenus(BMenu*);
virtual void AddDropContextMenus(BMenu*);
virtual void AddMenus();
virtual void AddFileMenu(BMenu* menu);
virtual void AddWindowMenu(BMenu* menu);
virtual void AddFavoritesMenu(BMenu* menu);
virtual void SetupNavigationMenu(const entry_ref*, BMenu*);
virtual void AddPoseContextMenu(BMenu*);
virtual void AddVolumeContextMenu(BMenu*);
virtual void AddWindowContextMenu(BMenu*);
virtual void AddDropContextMenu(BMenu*);
virtual void AddTrashContextMenu(BMenu*);
virtual void UpdateFileMenu(BMenu*);
virtual void UpdateFileMenuOrPoseContextMenu(BMenu*, MenuContext, const entry_ref* = NULL);
virtual void UpdateWindowMenu(BMenu*);
virtual void UpdateWindowContextMenu(BMenu*);
virtual void UpdateWindowMenuOrWindowContextMenu(BMenu*, MenuContext);
virtual void DetachSubmenus();
virtual void RepopulateMenus();
virtual void SetupNavigationMenu(BMenu*, const entry_ref*);
virtual void OpenDirectory();
virtual void OpenParent();
virtual void WindowActivated(bool state);
@@ -134,8 +147,6 @@ protected:
private:
bool SwitchDirToDesktopIfNeeded(entry_ref &ref);
bool CanOpenParent() const;
void SwitchDirMenuTo(const entry_ref* ref);
void AdjustButton();
bool SelectChildInParent(const entry_ref* parent, const node_ref* child);
void OpenSelectionCommon(BMessage*);
@@ -150,6 +161,7 @@ private:
BFilePanel* fClientObject;
int32 fSelectionIterator;
BMessage* fMessage;
BMenu* fFavoritesMenu;
BString fButtonText;
bool fHideWhenDone;
bool fIsTrackingMenu;
+2
View File
@@ -74,6 +74,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
SelectionWindow.cpp
Settings.cpp
SettingsViews.cpp
Shortcuts.cpp
SlowMenu.cpp
StatusWindow.cpp
TaskLoop.cpp
@@ -138,6 +139,7 @@ DoCatalogs libtracker.so :
RegExp.cpp
SelectionWindow.cpp
SettingsViews.cpp
Shortcuts.cpp
StatusWindow.cpp
TemplatesMenu.cpp
TextWidget.cpp
+51 -62
View File
@@ -92,6 +92,7 @@ All rights reserved.
#include "MimeTypes.h"
#include "Navigator.h"
#include "Pose.h"
#include "Shortcuts.h"
#include "Tests.h"
#include "Thread.h"
#include "Tracker.h"
@@ -1656,7 +1657,7 @@ void
BPoseView::AddPosesCompleted()
{
BContainerWindow* window = ContainerWindow();
if (window != NULL)
if (window != NULL && window->ShouldAddMenus())
window->AddMimeTypesToMenu();
// if we're not in icon mode then we need to check for poses that
@@ -2440,7 +2441,7 @@ BPoseView::MessageReceived(BMessage* message)
IdentifySelection(message->GetBool("force", false));
break;
case kEditItem:
case kEditName:
{
if (ActivePose())
break;
@@ -6232,17 +6233,14 @@ BPoseView::DeleteSelection(bool selectNext, bool confirm)
if (selectCount <= 0)
return;
if (!CheckVolumeReadOnly(
fSelectionList->ItemAt(0)->TargetModel()->EntryRef())) {
if (!CheckVolumeReadOnly(fSelectionList->ItemAt(0)->TargetModel()->EntryRef()))
return;
}
BObjectList<entry_ref>* entriesToDelete
= new BObjectList<entry_ref>(selectCount, true);
BObjectList<entry_ref>* entriesToDelete = new BObjectList<entry_ref>(selectCount, true);
for (int32 index = 0; index < selectCount; index++) {
entriesToDelete->AddItem(new entry_ref(
*fSelectionList->ItemAt(index)->TargetModel()->EntryRef()));
entry_ref* ref = new entry_ref(*fSelectionList->ItemAt(index)->TargetModel()->EntryRef());
entriesToDelete->AddItem(ref);
}
Delete(entriesToDelete, selectNext, confirm);
@@ -6271,8 +6269,7 @@ BPoseView::RestoreSelectionFromTrash(bool selectNext)
void
BPoseView::Delete(const entry_ref &ref, bool selectNext, bool confirm)
{
BObjectList<entry_ref>* entriesToDelete
= new BObjectList<entry_ref>(1, true);
BObjectList<entry_ref>* entriesToDelete = new BObjectList<entry_ref>(1, true);
entriesToDelete->AddItem(new entry_ref(ref));
Delete(entriesToDelete, selectNext, confirm);
@@ -6287,8 +6284,7 @@ BPoseView::Delete(BObjectList<entry_ref>* list, bool selectNext, bool confirm)
return;
}
BObjectList<FunctionObject>* taskList =
new BObjectList<FunctionObject>(2, true);
BObjectList<FunctionObject>* taskList = new BObjectList<FunctionObject>(2, true);
// first move selection to trash,
taskList->AddItem(NewFunctionObject(FSDeleteRefList, list, false, confirm));
@@ -6311,8 +6307,7 @@ BPoseView::Delete(BObjectList<entry_ref>* list, bool selectNext, bool confirm)
// deleted
Model* targetModel = TargetModel();
ASSERT(targetModel != NULL);
taskList->AddItem(NewMemberFunctionObject(
&TTracker::SelectPoseAtLocationSoon, tracker,
taskList->AddItem(NewMemberFunctionObject(&TTracker::SelectPoseAtLocationSoon, tracker,
*targetModel->NodeRef(), pointInPose));
}
}
@@ -6330,8 +6325,7 @@ BPoseView::RestoreItemsFromTrash(BObjectList<entry_ref>* list, bool selectNext)
return;
}
BObjectList<FunctionObject>* taskList =
new BObjectList<FunctionObject>(2, true);
BObjectList<FunctionObject>* taskList = new BObjectList<FunctionObject>(2, true);
// first restoree selection
taskList->AddItem(NewFunctionObject(FSRestoreRefList, list, false));
@@ -6354,8 +6348,7 @@ BPoseView::RestoreItemsFromTrash(BObjectList<entry_ref>* list, bool selectNext)
// restored
Model* targetModel = TargetModel();
ASSERT(targetModel != NULL);
taskList->AddItem(NewMemberFunctionObject(
&TTracker::SelectPoseAtLocationSoon, tracker,
taskList->AddItem(NewMemberFunctionObject(&TTracker::SelectPoseAtLocationSoon, tracker,
*targetModel->NodeRef(), pointInPose));
}
}
@@ -6391,8 +6384,7 @@ BPoseView::DoMoveToTrash()
if (TargetModel()->IsTrash())
return DeleteSelection(true, false);
bool shiftDown = (Window()->CurrentMessage()->FindInt32("modifiers")
& B_SHIFT_KEY) != 0;
bool shiftDown = (Window()->CurrentMessage()->FindInt32("modifiers") & B_SHIFT_KEY) != 0;
if (shiftDown)
DeleteSelection();
else
@@ -6751,7 +6743,7 @@ BPoseView::KeyDown(const char* bytes, int32 count)
if (message != NULL) {
int32 key;
if (message->FindInt32("key", &key) == B_OK && key == B_F2_KEY)
Window()->PostMessage(kEditItem, this);
Window()->PostMessage(kEditName, this);
}
break;
}
@@ -7472,7 +7464,7 @@ BPoseView::WasClickInPath(const BPose* pose, int32 index,
if (entry.GetRef(&ref) == B_OK) {
BMessage message(B_REFS_RECEIVED);
message.AddRef("refs", &ref);
be_app->PostMessage(&message);
Window()->PostMessage(&message);
return true;
}
@@ -8596,54 +8588,53 @@ BPoseView::SetDefaultPrinter()
void
BPoseView::OpenParent()
{
if (ParentIsRoot())
if (!CanOpenParent())
return;
BEntry entry(TargetModel()->EntryRef());
entry_ref ref;
if (FSGetParentVirtualDirectoryAware(entry, entry) != B_OK || entry.GetRef(&ref) != B_OK)
return;
BMessage message(B_REFS_RECEIVED);
message.AddRef("refs", &ref);
if (dynamic_cast<TTracker*>(be_app) != NULL) {
// add information about the child, so that we can select it in the parent view
message.AddData("nodeRefToSelect", B_RAW_TYPE, TargetModel()->NodeRef(), sizeof(node_ref));
if ((modifiers() & B_OPTION_KEY) != 0 && !IsFilePanel()) {
// if option down, add instructions to close the parent
message.AddData("nodeRefsToClose", B_RAW_TYPE, TargetModel()->NodeRef(),
sizeof(node_ref));
}
}
if (TrackerSettings().SingleWindowBrowse()) {
BMessage msg(kSwitchDirectory);
msg.AddRef("refs", &ref);
Window()->PostMessage(&msg);
} else {
be_app->PostMessage(&message);
}
BMessage message(kOpenParentDir);
message.AddRef("refs", TargetModel()->EntryRef());
Window()->PostMessage(&message);
}
bool
BPoseView::ParentIsRoot()
BPoseView::CanOpenParent()
{
if (IsDesktop() || TargetModel()->IsRoot())
return true;
TrackerSettings settings;
BEntry entry(TargetModel()->EntryRef());
// first determine if current entry is root
if (IsFilePanel()) {
if (settings.DesktopFilePanelRoot()) {
if (TargetModel()->IsDesktop())
return false;
} else if (TargetModel()->IsRoot()) {
return false;
}
} else {
// deny Desktop, allow Desktop folder
if (IsDesktop() || TargetModel()->IsRoot())
return false;
}
// override by holding control key
if ((modifiers() & B_CONTROL_KEY) != 0)
return true;
// file panel can go below root to Desktop
if (IsFilePanel() && settings.DesktopFilePanelRoot())
return true;
BEntry parentEntry;
if (FSGetParentVirtualDirectoryAware(entry, parentEntry) != B_OK)
return false;
BEntry entry(TargetModel()->EntryRef());
bool isRoot = FSGetParentVirtualDirectoryAware(entry, entry) == B_OK && FSIsRootDir(&entry);
if (isRoot && (TrackerSettings().SingleWindowBrowse() || TrackerSettings().ShowDisksIcon()))
return false;
// if show disks is on still one more level to go
bool parentIsRoot = FSIsRootDir(&parentEntry);
if (parentIsRoot && settings.ShowDisksIcon())
return true;
return isRoot;
return !parentIsRoot;
}
@@ -8692,8 +8683,7 @@ BPoseView::ClearSelection()
break;
}
} else {
int32 startIndex = FirstIndexAtOrBelow(
(int32)(bounds.top - IconPoseHeight()), true);
int32 startIndex = FirstIndexAtOrBelow((int32)(bounds.top - IconPoseHeight()), true);
int32 poseCount = fVSPoseList->CountItems();
for (int32 index = startIndex; index < poseCount; index++) {
BPose* pose = fVSPoseList->ItemAt(index);
@@ -8758,8 +8748,7 @@ BPoseView::ShowSelection(bool show)
break;
}
} else {
int32 startIndex = FirstIndexAtOrBelow(
(int32)(bounds.top - IconPoseHeight()), true);
int32 startIndex = FirstIndexAtOrBelow((int32)(bounds.top - IconPoseHeight()), true);
int32 poseCount = fVSPoseList->CountItems();
for (int32 index = startIndex; index < poseCount; index++) {
BPose* pose = fVSPoseList->ItemAt(index);
+1 -1
View File
@@ -276,7 +276,7 @@ public:
void UnmountSelectedVolumes();
virtual void OpenParent();
virtual bool ParentIsRoot();
virtual bool CanOpenParent();
virtual void OpenSelection(BPose* clicked_pose = NULL,
int32* index = NULL);
+10 -18
View File
@@ -46,6 +46,7 @@ All rights reserved.
#include "Commands.h"
#include "QueryContainerWindow.h"
#include "QueryPoseView.h"
#include "Shortcuts.h"
// #pragma mark - BQueryContainerWindow
@@ -93,28 +94,23 @@ BQueryContainerWindow::AddWindowMenu(BMenu* menu)
{
BMenuItem* item;
item = new BMenuItem(B_TRANSLATE("Resize to fit"),
new BMessage(kResizeToFit), 'Y');
item = Shortcuts()->ResizeToFitItem();
item->SetTarget(this);
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Select" B_UTF8_ELLIPSIS),
new BMessage(kShowSelectionWindow), 'A', B_SHIFT_KEY);
item = Shortcuts()->SelectItem();
item->SetTarget(PoseView());
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Select all"),
new BMessage(B_SELECT_ALL), 'A');
item = Shortcuts()->SelectAllItem();
item->SetTarget(PoseView());
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Invert selection"),
new BMessage(kInvertSelection), 'S');
item = Shortcuts()->InvertSelectionItem();
item->SetTarget(PoseView());
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Close"),
new BMessage(B_QUIT_REQUESTED), 'W');
item = Shortcuts()->CloseItem();
item->SetTarget(this);
menu->AddItem(item);
}
@@ -123,15 +119,11 @@ BQueryContainerWindow::AddWindowMenu(BMenu* menu)
void
BQueryContainerWindow::AddWindowContextMenus(BMenu* menu)
{
BMenuItem* resizeItem = new BMenuItem(B_TRANSLATE("Resize to fit"),
new BMessage(kResizeToFit), 'Y');
BMenuItem* resizeItem = Shortcuts()->ResizeToFitItem();
menu->AddItem(resizeItem);
menu->AddItem(new BMenuItem(B_TRANSLATE("Select" B_UTF8_ELLIPSIS),
new BMessage(kShowSelectionWindow), 'A', B_SHIFT_KEY));
menu->AddItem(new BMenuItem(B_TRANSLATE("Select all"),
new BMessage(B_SELECT_ALL), 'A'));
BMenuItem* closeItem = new BMenuItem(B_TRANSLATE("Close"),
new BMessage(B_QUIT_REQUESTED), 'W');
menu->AddItem(Shortcuts()->SelectItem());
menu->AddItem(Shortcuts()->SelectAllItem());
BMenuItem* closeItem = Shortcuts()->CloseItem();
menu->AddItem(closeItem);
// target items as needed
File diff suppressed because it is too large Load Diff
+230
View File
@@ -0,0 +1,230 @@
/*
* Copyright 2020-2024 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* John Scipione, jscipione@gmail.com
*/
#ifndef _SHORTCUTS_H
#define _SHORTCUTS_H
#include <SupportDefs.h>
#include "ContainerWindow.h"
class BMenu;
class BMenuItem;
namespace BPrivate {
class BPoseView;
class TShortcuts {
public:
TShortcuts();
TShortcuts(BContainerWindow* window);
// build item
BMenuItem* AddOnsItem();
const char* AddOnsLabel();
BMenuItem* ArrangeByItem();
const char* ArrangeByLabel();
BMenuItem* AddPrinterItem();
const char* AddPrinterLabel();
BMenuItem* CleanupItem();
const char* CleanupLabel();
int32 CleanupCommand();
BMenuItem* CloseItem();
const char* CloseLabel();
int32 CloseCommand();
BMenuItem* CloseAllInWorkspaceItem();
const char* CloseAllInWorkspaceLabel();
BMenuItem* CopyItem();
const char* CopyLabel();
int32 CopyCommand();
BMenuItem* CopyToItem();
BMenuItem* CopyToItem(BMenu*);
const char* CopyToLabel();
BMenuItem* CreateLinkItem();
BMenuItem* CreateLinkItem(BMenu*);
const char* CreateLinkLabel();
int32 CreateLinkCommand();
BMenuItem* CreateLinkHereItem();
const char* CreateLinkHereLabel();
int32 CreateLinkHereCommand();
BMenuItem* CutItem();
const char* CutLabel();
int32 CutCommand();
BMenuItem* DeleteItem();
const char* DeleteLabel();
BMenuItem* DuplicateItem();
const char* DuplicateLabel();
BMenuItem* EditNameItem();
const char* EditNameLabel();
BMenuItem* EditQueryItem();
const char* EditQueryLabel();
BMenuItem* EmptyTrashItem();
const char* EmptyTrashLabel();
BMenuItem* FindItem();
const char* FindLabel();
BMenuItem* GetInfoItem();
const char* GetInfoLabel();
BMenuItem* IdentifyItem();
const char* IdentifyLabel();
BMenuItem* InvertSelectionItem();
const char* InvertSelectionLabel();
BMenuItem* MakeActivePrinterItem();
const char* MakeActivePrinterLabel();
BMenuItem* MountItem();
BMenuItem* MountItem(BMenu*);
const char* MountLabel();
BMenuItem* MoveToItem();
BMenuItem* MoveToItem(BMenu*);
const char* MoveToLabel();
BMenuItem* MoveToTrashItem();
const char* MoveToTrashLabel();
int32 MoveToTrashCommand();
BMenuItem* NewFolderItem();
const char* NewFolderLabel();
BMenuItem* NewTemplatesItem();
BMenuItem* NewTemplatesItem(BMenu*);
const char* NewTemplatesLabel();
BMenuItem* OpenItem();
const char* OpenLabel();
BMenuItem* OpenParentItem();
const char* OpenParentLabel();
BMenuItem* OpenWithItem();
BMenuItem* OpenWithItem(BMenu*);
const char* OpenWithLabel();
BMenuItem* PasteItem();
const char* PasteLabel();
int32 PasteCommand();
BMenuItem* RestoreItem();
const char* RestoreLabel();
BMenuItem* ReverseOrderItem();
const char* ReverseOrderLabel();
BMenuItem* ResizeToFitItem();
const char* ResizeToFitLabel();
BMenuItem* SelectItem();
const char* SelectLabel();
BMenuItem* SelectAllItem();
const char* SelectAllLabel();
BMenuItem* UnmountItem();
const char* UnmountLabel();
// update item
void Update(BMenu*);
void UpdateAddOnsItem(BMenuItem*);
void UpdateAddPrinterItem(BMenuItem*);
void UpdateArrangeByItem(BMenuItem*);
void UpdateCleanupItem(BMenuItem*);
void UpdateCloseAllInWorkspaceItem(BMenuItem*);
void UpdateCloseItem(BMenuItem*);
void UpdateCopyItem(BMenuItem*);
void UpdateCopyToItem(BMenuItem*);
void UpdateCreateLinkItem(BMenuItem*);
void UpdateCreateLinkHereItem(BMenuItem*);
void UpdateCutItem(BMenuItem*);
void UpdateDeleteItem(BMenuItem*);
void UpdateDuplicateItem(BMenuItem*);
void UpdateEditNameItem(BMenuItem*);
void UpdateEditQueryItem(BMenuItem*);
void UpdateEmptyTrashItem(BMenuItem*);
void UpdateFindItem(BMenuItem*);
void UpdateGetInfoItem(BMenuItem*);
void UpdateIdentifyItem(BMenuItem*);
void UpdateInvertSelectionItem(BMenuItem*);
void UpdateMakeActivePrinterItem(BMenuItem*);
void UpdateMoveToItem(BMenuItem*);
void UpdateMoveToTrashItem(BMenuItem*);
void UpdateNewFolderItem(BMenuItem*);
void UpdateNewTemplatesItem(BMenuItem*);
void UpdateOpenItem(BMenuItem*);
void UpdateOpenParentItem(BMenuItem*);
void UpdateOpenWithItem(BMenuItem*);
void UpdatePasteItem(BMenuItem*);
void UpdateResizeToFitItem(BMenuItem*);
void UpdateRestoreItem(BMenuItem*);
void UpdateReverseOrderItem(BMenuItem*);
void UpdateSelectItem(BMenuItem*);
void UpdateSelectAllItem(BMenuItem*);
void UpdateUnmountItem(BMenuItem*);
// convenience methods
BMenuItem* FindItem(BMenu* menu, int32 command1, int32 command2);
BPoseView* PoseView() const;
bool IsCurrentFocusOnTextView() const;
bool IsDesktop() const;
bool IsQuery() const;
bool IsQueryTemplate() const;
bool IsRoot() const;
bool InTrash() const;
bool IsTrash() const;
bool IsVirtualDirectory() const;
bool IsVolume() const;
bool HasSelection() const;
bool SelectionIsReadOnly() const;
bool TargetIsReadOnly() const;
private:
BContainerWindow* fContainerWindow;
bool fInWindow;
};
inline BPoseView*
TShortcuts::PoseView() const
{
return fInWindow ? fContainerWindow->PoseView() : NULL;
}
} // namespace BPrivate
using namespace BPrivate;
#endif // _SHORTCUTS_H
+6 -34
View File
@@ -289,41 +289,13 @@ TTracker::TTracker()
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();
// create Desktop window and lock it
AutoLock<WindowList> lock(&fWindowList);
BContainerWindow* deskWindow = new BDeskWindow(&fWindowList);
AutoLock<BWindow> windowLock(deskWindow);
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;
}
// init Desktop now that pose view is created and window is locked
deskWindow->Init();
}
+11 -20
View File
@@ -49,6 +49,7 @@ All rights reserved.
#include <AutoLocker.h>
#include "Commands.h"
#include "Shortcuts.h"
#include "VirtualDirectoryManager.h"
#include "VirtualDirectoryPoseView.h"
@@ -134,33 +135,27 @@ VirtualDirectoryWindow::AddWindowMenu(BMenu* menu)
{
BMenuItem* item;
item = new BMenuItem(B_TRANSLATE("Resize to fit"),
new BMessage(kResizeToFit), 'Y');
item = Shortcuts()->ResizeToFitItem();
item->SetTarget(this);
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Select" B_UTF8_ELLIPSIS),
new BMessage(kShowSelectionWindow), 'A', B_SHIFT_KEY);
item = Shortcuts()->SelectItem();
item->SetTarget(PoseView());
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Select all"),
new BMessage(B_SELECT_ALL), 'A');
item = Shortcuts()->SelectAllItem();
item->SetTarget(this);
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Invert selection"),
new BMessage(kInvertSelection), 'S');
item = Shortcuts()->InvertSelectionItem();
item->SetTarget(PoseView());
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Open parent"),
new BMessage(kOpenParentDir), B_UP_ARROW);
item = Shortcuts()->OpenParentItem();
item->SetTarget(PoseView());
menu->AddItem(item);
item = new BMenuItem(B_TRANSLATE("Close"),
new BMessage(B_QUIT_REQUESTED), 'W');
item = Shortcuts()->CloseItem();
item->SetTarget(this);
menu->AddItem(item);
}
@@ -169,15 +164,11 @@ VirtualDirectoryWindow::AddWindowMenu(BMenu* menu)
void
VirtualDirectoryWindow::AddWindowContextMenus(BMenu* menu)
{
BMenuItem* resizeItem = new BMenuItem(B_TRANSLATE("Resize to fit"),
new BMessage(kResizeToFit), 'Y');
BMenuItem* resizeItem = Shortcuts()->ResizeToFitItem();
menu->AddItem(resizeItem);
menu->AddItem(new BMenuItem(B_TRANSLATE("Select" B_UTF8_ELLIPSIS),
new BMessage(kShowSelectionWindow), 'A', B_SHIFT_KEY));
menu->AddItem(new BMenuItem(B_TRANSLATE("Select all"),
new BMessage(B_SELECT_ALL), 'A'));
BMenuItem* closeItem = new BMenuItem(B_TRANSLATE("Close"),
new BMessage(B_QUIT_REQUESTED), 'W');
menu->AddItem(Shortcuts()->SelectItem());
menu->AddItem(Shortcuts()->SelectAllItem());
BMenuItem* closeItem = Shortcuts()->CloseItem();
menu->AddItem(closeItem);
// target items as needed
menu->SetTargetForItems(PoseView());
+7 -11
View File
@@ -55,6 +55,7 @@ All rights reserved.
#include "Model.h"
#include "NavMenu.h"
#include "PoseView.h"
#include "Shortcuts.h"
#include "Tracker.h"
@@ -333,7 +334,7 @@ HeaderView::MouseDown(BPoint where)
Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons);
if (SecondaryMouseButtonDown(modifiers(), buttons)) {
// Show contextual menu
BPopUpMenu* contextMenu = new BPopUpMenu("FileContext", false, false);
BPopUpMenu* contextMenu = new BPopUpMenu("PoseContext", false, false);
if (contextMenu != NULL) {
BuildContextMenu(contextMenu);
contextMenu->SetAsyncAutoDestruct(true);
@@ -581,17 +582,14 @@ HeaderView::BuildContextMenu(BMenu* parent)
navigationItem->SetTarget(be_app);
}
parent->AddItem(new BMenuItem(B_TRANSLATE("Open"),
new BMessage(kOpenSelection), 'O'));
parent->AddItem(TShortcuts().OpenItem());
if (!model.IsDesktop() && !model.IsRoot() && !model.IsTrash()) {
parent->AddItem(new BMenuItem(B_TRANSLATE("Edit name"),
new BMessage(kEditItem), 'E'));
parent->AddItem(TShortcuts().EditNameItem());
parent->AddSeparatorItem();
if (fModel->IsVolume()) {
BMenuItem* item = new BMenuItem(B_TRANSLATE("Unmount"),
new BMessage(kUnmountVolume), 'U');
BMenuItem* item = TShortcuts().UnmountItem();
parent->AddItem(item);
// volume model, enable/disable the Unmount item
BVolume boot;
@@ -604,12 +602,10 @@ HeaderView::BuildContextMenu(BMenu* parent)
}
if (!model.IsRoot() && !model.IsVolume() && !model.IsTrash())
parent->AddItem(new BMenuItem(B_TRANSLATE("Identify"),
new BMessage(kIdentifyEntry)));
parent->AddItem(TShortcuts().IdentifyItem());
if (model.IsTrash())
parent->AddItem(new BMenuItem(B_TRANSLATE("Empty Trash"),
new BMessage(kEmptyTrash)));
parent->AddItem(TShortcuts().EmptyTrashItem());
BMenuItem* sizeItem = NULL;
if (model.IsDirectory() && !model.IsVolume() && !model.IsRoot()) {
+2 -2
View File
@@ -113,7 +113,7 @@ BInfoWindow::BInfoWindow(Model* model, int32 group_index,
if (list != NULL)
list->AddItem(this);
AddShortcut('E', 0, new BMessage(kEditItem));
AddShortcut('E', 0, new BMessage(kEditName));
AddShortcut('O', 0, new BMessage(kOpenSelection));
AddShortcut('U', 0, new BMessage(kUnmountVolume));
AddShortcut('P', 0, new BMessage(kPermissionsSelected));
@@ -266,7 +266,7 @@ BInfoWindow::MessageReceived(BMessage* message)
break;
}
case kEditItem:
case kEditName:
{
BEntry entry(fModel->EntryRef());
fHeaderView->BeginEditingTitle();