Tracker: Reimplement BSlowContextPopup as BPopUpNavMenu.
BSlowContextPopup was mostly a duplicate class of BNavMenu only on top of BPopUpMenu instead of BMenu. Now, BPopUpNavMenu just subclasses BNavMenu and adds the few features of BPopUpMenu neccessary. Drag-and-drop of files using the pop-up nav menu seems to still work fine. Change-Id: Ic1f49c5bed60fff7a3076a22f74aebc6eba51d57
This commit is contained in:
parent
18ee9c8397
commit
8e8c7a073f
@ -148,6 +148,30 @@ protected:
|
||||
TrackingHookData fTrackingHook;
|
||||
};
|
||||
|
||||
|
||||
class BPopUpNavMenu : public BNavMenu {
|
||||
public:
|
||||
BPopUpNavMenu(const char* title);
|
||||
~BPopUpNavMenu();
|
||||
|
||||
void ClearMenu();
|
||||
|
||||
void Go(BPoint where);
|
||||
bool IsShowing() const;
|
||||
|
||||
protected:
|
||||
BPoint ScreenLocation();
|
||||
|
||||
private:
|
||||
void _WaitForTrackThread();
|
||||
static int32 _TrackThread(void* menu);
|
||||
|
||||
private:
|
||||
BPoint fWhere;
|
||||
thread_id fTrackThread;
|
||||
};
|
||||
|
||||
|
||||
// Spring Loaded Folder convenience routines
|
||||
// used in both Tracker and Deskbar
|
||||
#ifndef _IMPEXP_TRACKER
|
||||
|
@ -865,7 +865,7 @@ BContainerWindow::AddContextMenus()
|
||||
fDropContextMenu = new BPopUpMenu("DropContext", false, false);
|
||||
AddDropContextMenus(fDropContextMenu);
|
||||
|
||||
fDragContextMenu = new BSlowContextMenu("DragContext");
|
||||
fDragContextMenu = new BPopUpNavMenu("DragContext");
|
||||
// will get added and built dynamically in ShowContextMenu
|
||||
|
||||
fTrashContextMenu = new BPopUpMenu("TrashContext", false, false);
|
||||
@ -2849,7 +2849,7 @@ BContainerWindow::ShowContextMenu(BPoint where, const entry_ref* ref)
|
||||
|
||||
// this is now asynchronous so that we don't
|
||||
// deadlock in Window::Quit,
|
||||
fDragContextMenu->Go(global, true, false, true);
|
||||
fDragContextMenu->Go(global);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -41,7 +41,7 @@ All rights reserved.
|
||||
|
||||
#include "LockingList.h"
|
||||
#include "Model.h"
|
||||
#include "SlowContextPopup.h"
|
||||
#include "NavMenu.h"
|
||||
#include "TaskLoop.h"
|
||||
|
||||
|
||||
@ -294,7 +294,7 @@ protected:
|
||||
BPopUpMenu* fDropContextMenu;
|
||||
BPopUpMenu* fVolumeContextMenu;
|
||||
BPopUpMenu* fTrashContextMenu;
|
||||
BSlowContextMenu* fDragContextMenu;
|
||||
BPopUpNavMenu* fDragContextMenu;
|
||||
BMenuItem* fMoveToItem;
|
||||
BMenuItem* fCopyToItem;
|
||||
BMenuItem* fCreateLinkItem;
|
||||
|
@ -73,7 +73,6 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
SelectionWindow.cpp
|
||||
Settings.cpp
|
||||
SettingsViews.cpp
|
||||
SlowContextPopup.cpp
|
||||
SlowMenu.cpp
|
||||
StatusWindow.cpp
|
||||
TaskLoop.cpp
|
||||
@ -137,7 +136,6 @@ DoCatalogs libtracker.so :
|
||||
RegExp.cpp
|
||||
SelectionWindow.cpp
|
||||
SettingsViews.cpp
|
||||
SlowContextPopup.cpp
|
||||
StatusWindow.cpp
|
||||
TemplatesMenu.cpp
|
||||
TextWidget.cpp
|
||||
|
@ -900,3 +900,82 @@ BNavMenu::SetTrackingHookDeep(BMenu* menu, bool (*func)(BMenu*, void*),
|
||||
SetTrackingHookDeep(submenu, func, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - BPopUpNavMenu
|
||||
|
||||
|
||||
BPopUpNavMenu::BPopUpNavMenu(const char* title)
|
||||
:
|
||||
BNavMenu(title, B_REFS_RECEIVED, BMessenger(), NULL, NULL),
|
||||
fTrackThread(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BPopUpNavMenu::~BPopUpNavMenu()
|
||||
{
|
||||
_WaitForTrackThread();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BPopUpNavMenu::_WaitForTrackThread()
|
||||
{
|
||||
if (fTrackThread >= 0) {
|
||||
status_t status;
|
||||
while (wait_for_thread(fTrackThread, &status) == B_INTERRUPTED)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BPopUpNavMenu::ClearMenu()
|
||||
{
|
||||
RemoveItems(0, CountItems(), true);
|
||||
|
||||
fMenuBuilt = false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BPopUpNavMenu::Go(BPoint where)
|
||||
{
|
||||
_WaitForTrackThread();
|
||||
|
||||
fWhere = where;
|
||||
|
||||
fTrackThread = spawn_thread(_TrackThread, "popup", B_DISPLAY_PRIORITY, this);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BPopUpNavMenu::IsShowing() const
|
||||
{
|
||||
return Window() != NULL && !Window()->IsHidden();
|
||||
}
|
||||
|
||||
|
||||
BPoint
|
||||
BPopUpNavMenu::ScreenLocation()
|
||||
{
|
||||
return fWhere;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BPopUpNavMenu::_TrackThread(void* _menu)
|
||||
{
|
||||
BPopUpNavMenu* menu = static_cast<BPopUpNavMenu*>(_menu);
|
||||
|
||||
menu->Show();
|
||||
|
||||
BMenuItem* result = menu->Track();
|
||||
if (result != NULL)
|
||||
static_cast<BInvoker*>(result)->Invoke();
|
||||
|
||||
menu->Hide();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,562 +0,0 @@
|
||||
/*
|
||||
Open Tracker License
|
||||
|
||||
Terms and Conditions
|
||||
|
||||
Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice applies to all licensees
|
||||
and shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Be Incorporated shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings in
|
||||
this Software without prior written authorization from Be Incorporated.
|
||||
|
||||
Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
|
||||
of Be Incorporated in the United States and other countries. Other brand product
|
||||
names are registered trademarks or trademarks of their respective holders.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Debug.h>
|
||||
|
||||
#include <Application.h>
|
||||
#include <Catalog.h>
|
||||
#include <Directory.h>
|
||||
#include <Locale.h>
|
||||
#include <Path.h>
|
||||
#include <Query.h>
|
||||
#include <StopWatch.h>
|
||||
#include <VolumeRoster.h>
|
||||
#include <Volume.h>
|
||||
|
||||
#include "Attributes.h"
|
||||
#include "Commands.h"
|
||||
#include "ContainerWindow.h"
|
||||
#include "DesktopPoseView.h"
|
||||
#include "FSUtils.h"
|
||||
#include "FunctionObject.h"
|
||||
#include "IconMenuItem.h"
|
||||
#include "PoseView.h"
|
||||
#include "QueryPoseView.h"
|
||||
#include "SlowContextPopup.h"
|
||||
#include "Thread.h"
|
||||
#include "Tracker.h"
|
||||
#include "VirtualDirectoryEntryList.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "SlowContextPopup"
|
||||
|
||||
|
||||
// #pragma mark - BSlowContextMenu
|
||||
|
||||
|
||||
BSlowContextMenu::BSlowContextMenu(const char* title)
|
||||
:
|
||||
BPopUpMenu(title, false, false),
|
||||
fMenuBuilt(false),
|
||||
fMessage(B_REFS_RECEIVED),
|
||||
fParentWindow(NULL),
|
||||
fVolsOnly(false),
|
||||
fItemList(NULL),
|
||||
fContainer(NULL),
|
||||
fIteratingDesktop(false),
|
||||
fTypesList(NULL),
|
||||
fIsShowing(false)
|
||||
{
|
||||
InitIconPreloader();
|
||||
|
||||
SetFont(be_plain_font);
|
||||
SetTriggersEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
BSlowContextMenu::~BSlowContextMenu()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::AttachedToWindow()
|
||||
{
|
||||
// showing flag is set immediately as
|
||||
// it may take a while to build the menu's
|
||||
// contents.
|
||||
//
|
||||
// it should get set only once when Go is called
|
||||
// and will get reset in DetachedFromWindow
|
||||
//
|
||||
// this flag is used in ContainerWindow::ShowContextMenu
|
||||
// to determine whether we should show this menu, and
|
||||
// the only reason we need to do this is because this
|
||||
// menu is spawned ::Go as an asynchronous menu, which
|
||||
// is done because we will deadlock if the target's
|
||||
// window is open... so there
|
||||
fIsShowing = true;
|
||||
|
||||
BPopUpMenu::AttachedToWindow();
|
||||
|
||||
SpringLoadedFolderSetMenuStates(this, fTypesList);
|
||||
|
||||
// allow an opportunity to reset the target for each of the items
|
||||
SetTargetForItems(Target());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::DetachedFromWindow()
|
||||
{
|
||||
// see note above in AttachedToWindow
|
||||
fIsShowing = false;
|
||||
|
||||
// does this need to set this to null?
|
||||
// the parent, handling dnd should set this
|
||||
// appropriately
|
||||
//
|
||||
// if this changes, BeMenu and RecentsMenu
|
||||
// in Deskbar should also change
|
||||
fTypesList = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::SetNavDir(const entry_ref* ref)
|
||||
{
|
||||
ForceRebuild();
|
||||
// reset the slow menu building mechanism so we can add more stuff
|
||||
|
||||
fNavDir = *ref;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::ForceRebuild()
|
||||
{
|
||||
ClearMenuBuildingState();
|
||||
fMenuBuilt = false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BSlowContextMenu::NeedsToRebuild() const
|
||||
{
|
||||
return !fMenuBuilt;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::ClearMenu()
|
||||
{
|
||||
RemoveItems(0, CountItems(), true);
|
||||
|
||||
fMenuBuilt = false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::ClearMenuBuildingState()
|
||||
{
|
||||
delete fContainer;
|
||||
fContainer = NULL;
|
||||
|
||||
// item list is non-owning, need to delete the items because
|
||||
// they didn't get added to the menu
|
||||
if (fItemList) {
|
||||
RemoveItems(0, fItemList->CountItems(), true);
|
||||
delete fItemList;
|
||||
fItemList = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const int32 kItemsToAddChunk = 20;
|
||||
const bigtime_t kMaxTimeBuildingMenu = 200000;
|
||||
|
||||
|
||||
bool
|
||||
BSlowContextMenu::AddDynamicItem(add_state state)
|
||||
{
|
||||
if (fMenuBuilt)
|
||||
return false;
|
||||
|
||||
if (state == B_ABORT) {
|
||||
ClearMenuBuildingState();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (state == B_INITIAL_ADD && !StartBuildingItemList()) {
|
||||
ClearMenuBuildingState();
|
||||
return false;
|
||||
}
|
||||
|
||||
bigtime_t timeToBail = system_time() + kMaxTimeBuildingMenu;
|
||||
for (int32 count = 0; count < kItemsToAddChunk; count++) {
|
||||
if (!AddNextItem()) {
|
||||
fMenuBuilt = true;
|
||||
DoneBuildingItemList();
|
||||
ClearMenuBuildingState();
|
||||
return false;
|
||||
// done with menu, don't call again
|
||||
}
|
||||
if (system_time() > timeToBail)
|
||||
// we have been in here long enough, come back later
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
// call me again, got more to show
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BSlowContextMenu::StartBuildingItemList()
|
||||
{
|
||||
// return false when done building
|
||||
BEntry entry;
|
||||
|
||||
if (fNavDir.device < 0 || entry.SetTo(&fNavDir) != B_OK
|
||||
|| !entry.Exists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fItemList = new BObjectList<BMenuItem>(50);
|
||||
|
||||
fIteratingDesktop = false;
|
||||
|
||||
BDirectory parent;
|
||||
status_t err = entry.GetParent(&parent);
|
||||
|
||||
// if ref is the root item then build list of volume root dirs
|
||||
fVolsOnly = (err == B_ENTRY_NOT_FOUND);
|
||||
|
||||
if (fVolsOnly)
|
||||
return true;
|
||||
|
||||
Model startModel(&entry, true);
|
||||
if (startModel.InitCheck() != B_OK || !startModel.IsContainer())
|
||||
return false;
|
||||
|
||||
if (startModel.IsQuery()) {
|
||||
fContainer = new QueryEntryListCollection(&startModel);
|
||||
} else if (startModel.IsVirtualDirectory()) {
|
||||
fContainer = new VirtualDirectoryEntryList(&startModel);
|
||||
} else if (startModel.IsDesktop()) {
|
||||
fIteratingDesktop = true;
|
||||
fContainer = DesktopPoseView::InitDesktopDirentIterator(0,
|
||||
startModel.EntryRef());
|
||||
AddRootItemsIfNeeded();
|
||||
AddTrashItem();
|
||||
} else {
|
||||
BDirectory* directory = dynamic_cast<BDirectory*>(
|
||||
startModel.Node());
|
||||
|
||||
ASSERT(directory != NULL);
|
||||
|
||||
if (directory != NULL)
|
||||
fContainer = new DirectoryEntryList(*directory);
|
||||
}
|
||||
|
||||
if (fContainer->InitCheck() != B_OK)
|
||||
return false;
|
||||
|
||||
fContainer->Rewind();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::AddRootItemsIfNeeded()
|
||||
{
|
||||
BVolumeRoster roster;
|
||||
roster.Rewind();
|
||||
BVolume volume;
|
||||
while (roster.GetNextVolume(&volume) == B_OK) {
|
||||
BDirectory root;
|
||||
BEntry entry;
|
||||
if (!volume.IsPersistent()
|
||||
|| volume.GetRootDirectory(&root) != B_OK
|
||||
|| root.GetEntry(&entry) != B_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Model model(&entry);
|
||||
AddOneItem(&model);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::AddTrashItem()
|
||||
{
|
||||
BPath path;
|
||||
if (find_directory(B_TRASH_DIRECTORY, &path) == B_OK) {
|
||||
BEntry entry(path.Path());
|
||||
Model model(&entry);
|
||||
AddOneItem(&model);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BSlowContextMenu::AddNextItem()
|
||||
{
|
||||
if (fVolsOnly) {
|
||||
BuildVolumeMenu();
|
||||
return false;
|
||||
}
|
||||
|
||||
// limit nav menus to 500 items only
|
||||
if (fItemList->CountItems() > 500)
|
||||
return false;
|
||||
|
||||
BEntry entry;
|
||||
if (fContainer->GetNextEntry(&entry) != B_OK)
|
||||
// we're finished
|
||||
return false;
|
||||
|
||||
Model model(&entry, true);
|
||||
if (model.InitCheck() != B_OK) {
|
||||
// PRINT(("not showing hidden item %s, wouldn't open\n", model->Name()));
|
||||
return true;
|
||||
}
|
||||
|
||||
PoseInfo poseInfo;
|
||||
|
||||
if (model.Node()) {
|
||||
model.Node()->ReadAttr(kAttrPoseInfo, B_RAW_TYPE, 0,
|
||||
&poseInfo, sizeof(poseInfo));
|
||||
}
|
||||
|
||||
model.CloseNode();
|
||||
|
||||
if (!BPoseView::PoseVisible(&model, &poseInfo)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
AddOneItem(&model);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::AddOneItem(Model* model)
|
||||
{
|
||||
BMenuItem* item = NewModelItem(model, &fMessage, fMessenger, false,
|
||||
dynamic_cast<BContainerWindow*>(fParentWindow), fTypesList,
|
||||
&fTrackingHook);
|
||||
if (item != NULL)
|
||||
fItemList->AddItem(item);
|
||||
}
|
||||
|
||||
|
||||
ModelMenuItem*
|
||||
BSlowContextMenu::NewModelItem(Model* model, const BMessage* invokeMessage,
|
||||
const BMessenger &target, bool suppressFolderHierarchy,
|
||||
BContainerWindow* parentWindow, const BObjectList<BString>* typeslist,
|
||||
TrackingHookData* hook)
|
||||
{
|
||||
if (model->InitCheck() != B_OK)
|
||||
return NULL;
|
||||
|
||||
entry_ref ref;
|
||||
bool container = false;
|
||||
if (model->IsSymLink()) {
|
||||
|
||||
Model* newResolvedModel = NULL;
|
||||
Model* result = model->LinkTo();
|
||||
|
||||
if (!result) {
|
||||
newResolvedModel = new Model(model->EntryRef(), true, true);
|
||||
|
||||
if (newResolvedModel->InitCheck() != B_OK) {
|
||||
// broken link, still can show though, bail
|
||||
delete newResolvedModel;
|
||||
newResolvedModel = NULL;
|
||||
}
|
||||
|
||||
result = newResolvedModel;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
BModelOpener opener(result);
|
||||
// open the model, if it ain't open already
|
||||
|
||||
PoseInfo poseInfo;
|
||||
|
||||
if (result->Node()) {
|
||||
result->Node()->ReadAttr(kAttrPoseInfo, B_RAW_TYPE, 0,
|
||||
&poseInfo, sizeof(poseInfo));
|
||||
}
|
||||
|
||||
result->CloseNode();
|
||||
|
||||
ref = *result->EntryRef();
|
||||
container = result->IsContainer();
|
||||
}
|
||||
model->SetLinkTo(result);
|
||||
} else {
|
||||
ref = *model->EntryRef();
|
||||
container = model->IsContainer();
|
||||
}
|
||||
|
||||
BMessage* message = new BMessage(*invokeMessage);
|
||||
message->AddRef("refs", model->EntryRef());
|
||||
|
||||
// Truncate the name if necessary
|
||||
BString truncatedString(model->Name());
|
||||
be_plain_font->TruncateString(&truncatedString, B_TRUNCATE_END,
|
||||
BNavMenu::GetMaxMenuWidth());
|
||||
|
||||
ModelMenuItem* item = NULL;
|
||||
if (!container || suppressFolderHierarchy) {
|
||||
item = new ModelMenuItem(model, truncatedString.String(), message);
|
||||
if (invokeMessage->what != B_REFS_RECEIVED)
|
||||
item->SetEnabled(false);
|
||||
} else {
|
||||
BNavMenu* menu = new BNavMenu(truncatedString.String(),
|
||||
invokeMessage->what, target, parentWindow, typeslist);
|
||||
|
||||
menu->SetNavDir(&ref);
|
||||
if (hook)
|
||||
menu->InitTrackingHook(hook->fTrackingHook, &(hook->fTarget),
|
||||
hook->fDragMessage);
|
||||
|
||||
item = new ModelMenuItem(model, menu);
|
||||
item->SetMessage(message);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::BuildVolumeMenu()
|
||||
{
|
||||
BVolumeRoster roster;
|
||||
BVolume volume;
|
||||
|
||||
roster.Rewind();
|
||||
while (roster.GetNextVolume(&volume) == B_OK) {
|
||||
|
||||
if (!volume.IsPersistent())
|
||||
continue;
|
||||
|
||||
BDirectory startDir;
|
||||
if (volume.GetRootDirectory(&startDir) == B_OK) {
|
||||
BEntry entry;
|
||||
startDir.GetEntry(&entry);
|
||||
|
||||
Model* model = new Model(&entry);
|
||||
if (model->InitCheck() != B_OK) {
|
||||
delete model;
|
||||
continue;
|
||||
}
|
||||
|
||||
BNavMenu* menu = new BNavMenu(model->Name(), fMessage.what,
|
||||
fMessenger, fParentWindow, fTypesList);
|
||||
|
||||
menu->SetNavDir(model->EntryRef());
|
||||
menu->InitTrackingHook(fTrackingHook.fTrackingHook,
|
||||
&(fTrackingHook.fTarget), fTrackingHook.fDragMessage);
|
||||
|
||||
ASSERT(menu->Name());
|
||||
|
||||
ModelMenuItem* item = new ModelMenuItem(model, menu);
|
||||
BMessage* message = new BMessage(fMessage);
|
||||
|
||||
message->AddRef("refs", model->EntryRef());
|
||||
item->SetMessage(message);
|
||||
fItemList->AddItem(item);
|
||||
ASSERT(item->Label());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::DoneBuildingItemList()
|
||||
{
|
||||
// add sorted items to menu
|
||||
if (TrackerSettings().SortFolderNamesFirst())
|
||||
fItemList->SortItems(&BNavMenu::CompareFolderNamesFirstOne);
|
||||
else
|
||||
fItemList->SortItems(&BNavMenu::CompareOne);
|
||||
|
||||
int32 count = fItemList->CountItems();
|
||||
for (int32 index = 0; index < count; index++)
|
||||
AddItem(fItemList->ItemAt(index));
|
||||
|
||||
fItemList->MakeEmpty();
|
||||
|
||||
if (!count) {
|
||||
BMenuItem* item = new BMenuItem(B_TRANSLATE("Empty folder"), 0);
|
||||
item->SetEnabled(false);
|
||||
AddItem(item);
|
||||
}
|
||||
|
||||
SetTargetForItems(fMessenger);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::SetTypesList(const BObjectList<BString>* list)
|
||||
{
|
||||
fTypesList = list;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::SetTarget(const BMessenger &target)
|
||||
{
|
||||
fMessenger = target;
|
||||
}
|
||||
|
||||
|
||||
TrackingHookData*
|
||||
BSlowContextMenu::InitTrackingHook(bool (*hook)(BMenu*, void*),
|
||||
const BMessenger* target, const BMessage* dragMessage)
|
||||
{
|
||||
fTrackingHook.fTrackingHook = hook;
|
||||
if (target)
|
||||
fTrackingHook.fTarget = *target;
|
||||
fTrackingHook.fDragMessage = dragMessage;
|
||||
SetTrackingHookDeep(this, hook, &fTrackingHook);
|
||||
return &fTrackingHook;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSlowContextMenu::SetTrackingHookDeep(BMenu* menu,
|
||||
bool (*func)(BMenu*, void*), void* state)
|
||||
{
|
||||
menu->SetTrackingHook(func, state);
|
||||
int32 count = menu->CountItems();
|
||||
for (int32 index = 0; index < count; index++) {
|
||||
BMenuItem* item = menu->ItemAt(index);
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
BMenu* submenu = item->Submenu();
|
||||
if (submenu)
|
||||
SetTrackingHookDeep(submenu, func, state);
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
/*
|
||||
Open Tracker License
|
||||
|
||||
Terms and Conditions
|
||||
|
||||
Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice applies to all licensees
|
||||
and shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Be Incorporated shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings in
|
||||
this Software without prior written authorization from Be Incorporated.
|
||||
|
||||
Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
|
||||
of Be Incorporated in the United States and other countries. Other brand product
|
||||
names are registered trademarks or trademarks of their respective holders.
|
||||
All rights reserved.
|
||||
*/
|
||||
#ifndef _SLOW_CONTEXT_POPUP_H
|
||||
#define _SLOW_CONTEXT_POPUP_H
|
||||
|
||||
|
||||
#include <PopUpMenu.h>
|
||||
#include "NavMenu.h"
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
class BSlowContextMenu : public BPopUpMenu {
|
||||
public:
|
||||
BSlowContextMenu(const char* title);
|
||||
virtual ~BSlowContextMenu();
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void DetachedFromWindow();
|
||||
|
||||
void SetNavDir(const entry_ref*);
|
||||
|
||||
void ClearMenu();
|
||||
|
||||
void ForceRebuild();
|
||||
bool NeedsToRebuild() const;
|
||||
// will cause menu to get rebuilt next time it is shown
|
||||
|
||||
void SetTarget(const BMessenger &);
|
||||
const BMessenger Target() const;
|
||||
|
||||
void SetTypesList(const BObjectList<BString>* list);
|
||||
const BObjectList<BString>* TypesList() const;
|
||||
|
||||
static ModelMenuItem* NewModelItem(Model*, const BMessage*,
|
||||
const BMessenger&, bool suppressFolderHierarchy = false,
|
||||
BContainerWindow* = NULL,
|
||||
const BObjectList<BString>* typeslist = NULL,
|
||||
TrackingHookData* hook = NULL);
|
||||
|
||||
TrackingHookData* InitTrackingHook(bool (*)(BMenu*, void*),
|
||||
const BMessenger* target, const BMessage* dragMessage);
|
||||
|
||||
const bool IsShowing() const;
|
||||
|
||||
protected:
|
||||
virtual bool AddDynamicItem(add_state state);
|
||||
virtual bool StartBuildingItemList();
|
||||
virtual bool AddNextItem();
|
||||
virtual void DoneBuildingItemList();
|
||||
virtual void ClearMenuBuildingState();
|
||||
|
||||
void BuildVolumeMenu();
|
||||
|
||||
void AddOneItem(Model*);
|
||||
void AddRootItemsIfNeeded();
|
||||
void AddTrashItem();
|
||||
static void SetTrackingHookDeep(BMenu*, bool (*)(BMenu*, void*), void*);
|
||||
|
||||
bool fMenuBuilt;
|
||||
|
||||
private:
|
||||
entry_ref fNavDir;
|
||||
BMessage fMessage;
|
||||
BMessenger fMessenger;
|
||||
BWindow* fParentWindow;
|
||||
|
||||
// menu building state
|
||||
bool fVolsOnly;
|
||||
BObjectList<BMenuItem>* fItemList;
|
||||
EntryListBase* fContainer;
|
||||
bool fIteratingDesktop;
|
||||
|
||||
const BObjectList<BString>* fTypesList;
|
||||
|
||||
TrackingHookData fTrackingHook;
|
||||
bool fIsShowing;
|
||||
// see note in AttachedToWindow
|
||||
};
|
||||
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
using namespace BPrivate;
|
||||
|
||||
|
||||
inline const BObjectList<BString>*
|
||||
BSlowContextMenu::TypesList() const
|
||||
{
|
||||
return fTypesList;
|
||||
}
|
||||
|
||||
|
||||
inline const BMessenger
|
||||
BSlowContextMenu::Target() const
|
||||
{
|
||||
return fMessenger;
|
||||
}
|
||||
|
||||
|
||||
inline const bool
|
||||
BSlowContextMenu::IsShowing() const
|
||||
{
|
||||
return fIsShowing;
|
||||
}
|
||||
|
||||
|
||||
#endif // _SLOW_CONTEXT_POPUP_H
|
Loading…
x
Reference in New Issue
Block a user