xref: /haiku/src/apps/deskbar/DeskbarMenu.cpp (revision 573f748c5f8fb7ed75beb0ceb7eb097d3ab0c038)
1323b6546SOliver Tappe /*
2323b6546SOliver Tappe Open Tracker License
3323b6546SOliver Tappe 
4323b6546SOliver Tappe Terms and Conditions
5323b6546SOliver Tappe 
6323b6546SOliver Tappe Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7323b6546SOliver Tappe 
8323b6546SOliver Tappe Permission is hereby granted, free of charge, to any person obtaining a copy of
9323b6546SOliver Tappe this software and associated documentation files (the "Software"), to deal in
10323b6546SOliver Tappe the Software without restriction, including without limitation the rights to
11323b6546SOliver Tappe use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12323b6546SOliver Tappe of the Software, and to permit persons to whom the Software is furnished to do
13323b6546SOliver Tappe so, subject to the following conditions:
14323b6546SOliver Tappe 
15323b6546SOliver Tappe The above copyright notice and this permission notice applies to all licensees
16323b6546SOliver Tappe and shall be included in all copies or substantial portions of the Software.
17323b6546SOliver Tappe 
18323b6546SOliver Tappe THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19323b6546SOliver Tappe IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20323b6546SOliver Tappe FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21323b6546SOliver Tappe BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22323b6546SOliver Tappe AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23323b6546SOliver Tappe WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24323b6546SOliver Tappe 
25323b6546SOliver Tappe Except as contained in this notice, the name of Be Incorporated shall not be
26323b6546SOliver Tappe used in advertising or otherwise to promote the sale, use or other dealings in
27323b6546SOliver Tappe this Software without prior written authorization from Be Incorporated.
28323b6546SOliver Tappe 
29323b6546SOliver Tappe Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered
30323b6546SOliver Tappe trademarks of Be Incorporated in the United States and other countries. Other
31323b6546SOliver Tappe brand product names are registered trademarks or trademarks of their respective
32323b6546SOliver Tappe holders.
33323b6546SOliver Tappe All rights reserved.
34323b6546SOliver Tappe */
35323b6546SOliver Tappe 
36323b6546SOliver Tappe #include <Debug.h>
37323b6546SOliver Tappe #include <Bitmap.h>
38323b6546SOliver Tappe #include <Catalog.h>
39323b6546SOliver Tappe #include <Dragger.h>
40323b6546SOliver Tappe #include <Locale.h>
41323b6546SOliver Tappe #include <Menu.h>
42323b6546SOliver Tappe #include <MenuItem.h>
43323b6546SOliver Tappe #include <Roster.h>
44323b6546SOliver Tappe 
45323b6546SOliver Tappe #include "DeskbarMenu.h"
46323b6546SOliver Tappe #include "BarApp.h"
47323b6546SOliver Tappe #include "BarView.h"
48323b6546SOliver Tappe #include "DeskbarUtils.h"
49323b6546SOliver Tappe #include "IconMenuItem.h"
50323b6546SOliver Tappe #include "MountMenu.h"
51323b6546SOliver Tappe #include "IconMenuItem.h"
52323b6546SOliver Tappe #include "MountMenu.h"
53323b6546SOliver Tappe #include "IconMenuItem.h"
54323b6546SOliver Tappe #include "MountMenu.h"
55323b6546SOliver Tappe #include "PublicCommands.h"
56323b6546SOliver Tappe #include "RecentItems.h"
57323b6546SOliver Tappe #include "StatusView.h"
58323b6546SOliver Tappe #include "tracker_private.h"
59323b6546SOliver Tappe 
60323b6546SOliver Tappe #undef B_TRANSLATE_CONTEXT
61323b6546SOliver Tappe #define B_TRANSLATE_CONTEXT "DeskbarMenu"
62323b6546SOliver Tappe 
63323b6546SOliver Tappe #define ROSTER_SIG "application/x-vnd.Be-ROST"
64323b6546SOliver Tappe 
65323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR
66323b6546SOliver Tappe 
67323b6546SOliver Tappe class DeskbarMountMenu : public BPrivate::MountMenu {
68323b6546SOliver Tappe 	public:
69323b6546SOliver Tappe 		DeskbarMountMenu(const char* name);
70323b6546SOliver Tappe 		virtual bool AddDynamicItem(add_state s);
71323b6546SOliver Tappe };
72323b6546SOliver Tappe 
73323b6546SOliver Tappe #endif
74323b6546SOliver Tappe 
75323b6546SOliver Tappe // #define SHOW_RECENT_FIND_ITEMS
76323b6546SOliver Tappe 
77323b6546SOliver Tappe namespace BPrivate {
78323b6546SOliver Tappe 	BMenu* TrackerBuildRecentFindItemsMenu(const char*);
79323b6546SOliver Tappe }
80323b6546SOliver Tappe 
81323b6546SOliver Tappe 
82323b6546SOliver Tappe using namespace BPrivate;
83323b6546SOliver Tappe 
84323b6546SOliver Tappe 
85323b6546SOliver Tappe //	#pragma mark -
86323b6546SOliver Tappe 
87323b6546SOliver Tappe 
88323b6546SOliver Tappe TDeskbarMenu::TDeskbarMenu(TBarView* barView)
89323b6546SOliver Tappe 	: BNavMenu("DeskbarMenu", B_REFS_RECEIVED, DefaultTarget()),
90323b6546SOliver Tappe 	fAddState(kStart),
91323b6546SOliver Tappe 	fBarView(barView)
92323b6546SOliver Tappe {
93323b6546SOliver Tappe }
94323b6546SOliver Tappe 
95323b6546SOliver Tappe 
96323b6546SOliver Tappe void
97323b6546SOliver Tappe TDeskbarMenu::AttachedToWindow()
98323b6546SOliver Tappe {
99323b6546SOliver Tappe 	if (fBarView && fBarView->LockLooper()) {
100323b6546SOliver Tappe 		if (fBarView->Dragging()) {
101323b6546SOliver Tappe 			SetTypesList(fBarView->CachedTypesList());
102323b6546SOliver Tappe 			SetTarget(BMessenger(fBarView));
103323b6546SOliver Tappe 			SetTrackingHookDeep(this, fBarView->MenuTrackingHook,
104323b6546SOliver Tappe 				fBarView->GetTrackingHookData());
105323b6546SOliver Tappe 			fBarView->DragStart();
106323b6546SOliver Tappe 		} else {
107323b6546SOliver Tappe 			SetTypesList(NULL);
108323b6546SOliver Tappe 			SetTarget(DefaultTarget());
109323b6546SOliver Tappe 			SetTrackingHookDeep(this, NULL, NULL);
110323b6546SOliver Tappe 		}
111323b6546SOliver Tappe 
112323b6546SOliver Tappe 		fBarView->UnlockLooper();
113323b6546SOliver Tappe 	}
114323b6546SOliver Tappe 
115323b6546SOliver Tappe 	BNavMenu::AttachedToWindow();
116323b6546SOliver Tappe }
117323b6546SOliver Tappe 
118323b6546SOliver Tappe 
119323b6546SOliver Tappe void
120323b6546SOliver Tappe TDeskbarMenu::DetachedFromWindow()
121323b6546SOliver Tappe {
122323b6546SOliver Tappe 	if (fBarView) {
123323b6546SOliver Tappe 		BLooper* looper = fBarView->Looper();
124323b6546SOliver Tappe 		if (looper && looper->Lock()) {
125323b6546SOliver Tappe 			fBarView->DragStop();
126323b6546SOliver Tappe 			looper->Unlock();
127323b6546SOliver Tappe 		}
128323b6546SOliver Tappe 	}
129323b6546SOliver Tappe 
130323b6546SOliver Tappe 	// don't call BNavMenu::DetachedFromWindow
131323b6546SOliver Tappe 	// it sets the TypesList to NULL
132323b6546SOliver Tappe 	BMenu::DetachedFromWindow();
133323b6546SOliver Tappe }
134323b6546SOliver Tappe 
135323b6546SOliver Tappe 
136323b6546SOliver Tappe bool
137323b6546SOliver Tappe TDeskbarMenu::StartBuildingItemList()
138323b6546SOliver Tappe {
139323b6546SOliver Tappe 	RemoveItems(0, CountItems(), true);
140323b6546SOliver Tappe 	fAddState = kStart;
141323b6546SOliver Tappe 	return BNavMenu::StartBuildingItemList();
142323b6546SOliver Tappe }
143323b6546SOliver Tappe 
144323b6546SOliver Tappe 
145323b6546SOliver Tappe void
146323b6546SOliver Tappe TDeskbarMenu::DoneBuildingItemList()
147323b6546SOliver Tappe {
148323b6546SOliver Tappe 	if (fItemList->CountItems() <= 0) {
149323b6546SOliver Tappe 		BMenuItem* item
150323b6546SOliver Tappe 			= new BMenuItem(B_TRANSLATE("<Deskbar folder is empty>"), 0);
151323b6546SOliver Tappe 		item->SetEnabled(false);
152323b6546SOliver Tappe 		AddItem(item);
153323b6546SOliver Tappe 	} else
154323b6546SOliver Tappe 		BNavMenu::DoneBuildingItemList();
155323b6546SOliver Tappe }
156323b6546SOliver Tappe 
157323b6546SOliver Tappe 
158323b6546SOliver Tappe bool
159323b6546SOliver Tappe TDeskbarMenu::AddNextItem()
160323b6546SOliver Tappe {
161323b6546SOliver Tappe 	if (fAddState == kStart)
162323b6546SOliver Tappe 		return AddStandardDeskbarMenuItems();
163323b6546SOliver Tappe 
164323b6546SOliver Tappe 	TrackingHookData* data = fBarView->GetTrackingHookData();
165323b6546SOliver Tappe 	if (fAddState == kAddingRecents) {
166323b6546SOliver Tappe 		static const char* recentTitle[] = {
167323b6546SOliver Tappe 			B_TRANSLATE_MARK("Recent documents"),
168323b6546SOliver Tappe 			B_TRANSLATE_MARK("Recent folders"),
169323b6546SOliver Tappe 			B_TRANSLATE_MARK("Recent applications")};
170323b6546SOliver Tappe 		const int recentType[] = {kRecentDocuments, kRecentFolders,
171323b6546SOliver Tappe 			kRecentApplications};
172323b6546SOliver Tappe 		const int recentTypes = 3;
173323b6546SOliver Tappe 		TRecentsMenu* recentItem[recentTypes];
174323b6546SOliver Tappe 
175323b6546SOliver Tappe 		bool enabled = false;
176323b6546SOliver Tappe 
177323b6546SOliver Tappe 		for (int i = 0; i < recentTypes; i++) {
178323b6546SOliver Tappe 			recentItem[i]
179323b6546SOliver Tappe 				= new TRecentsMenu(B_TRANSLATE_NOCOLLECT(recentTitle[i]),
180323b6546SOliver Tappe 					fBarView, recentType[i]);
181323b6546SOliver Tappe 
182323b6546SOliver Tappe 			if (recentItem[i])
183323b6546SOliver Tappe 				enabled |= recentItem[i]->RecentsEnabled();
184323b6546SOliver Tappe 		}
185323b6546SOliver Tappe 		if (enabled) {
186323b6546SOliver Tappe 			AddSeparatorItem();
187323b6546SOliver Tappe 
188323b6546SOliver Tappe 			for (int i = 0; i < recentTypes; i++) {
189323b6546SOliver Tappe 				if (!recentItem[i])
190323b6546SOliver Tappe 					continue;
191323b6546SOliver Tappe 
192323b6546SOliver Tappe 				if (recentItem[i]->RecentsEnabled()) {
193323b6546SOliver Tappe 					recentItem[i]->SetTypesList(TypesList());
194323b6546SOliver Tappe 					recentItem[i]->SetTarget(Target());
195323b6546SOliver Tappe 					AddItem(recentItem[i]);
196323b6546SOliver Tappe 				}
197323b6546SOliver Tappe 
198323b6546SOliver Tappe 				if (data && fBarView && fBarView->Dragging()) {
199323b6546SOliver Tappe 					recentItem[i]->InitTrackingHook(data->fTrackingHook,
200323b6546SOliver Tappe 						&data->fTarget, data->fDragMessage);
201323b6546SOliver Tappe 				}
202323b6546SOliver Tappe 			}
203323b6546SOliver Tappe 		}
204323b6546SOliver Tappe 
205323b6546SOliver Tappe 		AddSeparatorItem();
206323b6546SOliver Tappe 		fAddState = kAddingDeskbarMenu;
207323b6546SOliver Tappe 		return true;
208323b6546SOliver Tappe 	}
209323b6546SOliver Tappe 
210323b6546SOliver Tappe 	if (fAddState == kAddingDeskbarMenu) {
211323b6546SOliver Tappe 		// keep reentering and adding items
212323b6546SOliver Tappe 		// until this returns false
213323b6546SOliver Tappe 		bool done = BNavMenu::AddNextItem();
214323b6546SOliver Tappe 		BMenuItem* item = ItemAt(CountItems() - 1);
215323b6546SOliver Tappe 		if (item) {
216323b6546SOliver Tappe 			BNavMenu* menu = dynamic_cast<BNavMenu*>(item->Menu());
217323b6546SOliver Tappe 			if (menu) {
218323b6546SOliver Tappe 				if (data && fBarView->Dragging()) {
219323b6546SOliver Tappe 					menu->InitTrackingHook(data->fTrackingHook,
220323b6546SOliver Tappe 						&data->fTarget, data->fDragMessage);
221323b6546SOliver Tappe 				} else
222323b6546SOliver Tappe 					menu->InitTrackingHook(0, NULL, NULL);
223323b6546SOliver Tappe 			}
224323b6546SOliver Tappe 		}
225323b6546SOliver Tappe 
226323b6546SOliver Tappe 		if (!done)
227323b6546SOliver Tappe 			fAddState = kDone;
228323b6546SOliver Tappe 		return done;
229323b6546SOliver Tappe 	}
230323b6546SOliver Tappe 
231323b6546SOliver Tappe 	return false;
232323b6546SOliver Tappe }
233323b6546SOliver Tappe 
234323b6546SOliver Tappe 
235323b6546SOliver Tappe bool
236323b6546SOliver Tappe TDeskbarMenu::AddStandardDeskbarMenuItems()
237323b6546SOliver Tappe {
238323b6546SOliver Tappe 	bool dragging = false;
239323b6546SOliver Tappe 	if (fBarView)
240323b6546SOliver Tappe 		dragging = fBarView->Dragging();
241323b6546SOliver Tappe 
242323b6546SOliver Tappe 	BMenuItem* item;
243323b6546SOliver Tappe 	BRoster roster;
244323b6546SOliver Tappe 	if (!roster.IsRunning(kTrackerSignature)) {
245323b6546SOliver Tappe 		item = new BMenuItem(B_TRANSLATE("Restart Tracker"),
246323b6546SOliver Tappe 			new BMessage(kRestartTracker));
247323b6546SOliver Tappe 		AddItem(item);
248323b6546SOliver Tappe 		AddSeparatorItem();
249323b6546SOliver Tappe 	}
250323b6546SOliver Tappe 
251323b6546SOliver Tappe // One of them is used if HAIKU_DISTRO_COMPATIBILITY_OFFICIAL, and the other if
252323b6546SOliver Tappe // not. However, we want both of them to end up in the catalog, so we have to
253323b6546SOliver Tappe // make them visible to collectcatkeys in either case.
254323b6546SOliver Tappe #if defined(B_COLLECTING_CATKEYS)||defined(HAIKU_DISTRO_COMPATIBILITY_OFFICIAL)
255323b6546SOliver Tappe 	static const char* kAboutHaikuMenuItemStr = B_TRANSLATE_MARK(
256323b6546SOliver Tappe 		"About Haiku");
257323b6546SOliver Tappe #endif
258323b6546SOliver Tappe 
259323b6546SOliver Tappe #if defined(B_COLLECTING_CATKEYS)||!defined(HAIKU_DISTRO_COMPATIBILITY_OFFICIAL)
260323b6546SOliver Tappe 	static const char* kAboutThisSystemMenuItemStr = B_TRANSLATE_MARK(
261323b6546SOliver Tappe 		"About this system");
262323b6546SOliver Tappe #endif
263323b6546SOliver Tappe 
264323b6546SOliver Tappe 	item = new BMenuItem(
265323b6546SOliver Tappe #ifdef HAIKU_DISTRO_COMPATIBILITY_OFFICIAL
266323b6546SOliver Tappe 	B_TRANSLATE_NOCOLLECT(kAboutHaikuMenuItemStr)
267323b6546SOliver Tappe #else
268323b6546SOliver Tappe 	B_TRANSLATE_NOCOLLECT(kAboutThisSystemMenuItemStr)
269323b6546SOliver Tappe #endif
270323b6546SOliver Tappe 		, new BMessage(kShowSplash));
271323b6546SOliver Tappe 	item->SetEnabled(!dragging);
272323b6546SOliver Tappe 	AddItem(item);
273323b6546SOliver Tappe 
274323b6546SOliver Tappe 	static const char* kFindMenuItemStr
275323b6546SOliver Tappe 		= B_TRANSLATE_MARK("Find" B_UTF8_ELLIPSIS);
276323b6546SOliver Tappe 
277323b6546SOliver Tappe #ifdef SHOW_RECENT_FIND_ITEMS
278323b6546SOliver Tappe 	item = new BMenuItem(
279323b6546SOliver Tappe 		TrackerBuildRecentFindItemsMenu(kFindMenuItemStr),
280323b6546SOliver Tappe 		new BMessage(kFindButton));
281323b6546SOliver Tappe #else
282323b6546SOliver Tappe 	item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kFindMenuItemStr),
283323b6546SOliver Tappe 		new BMessage(kFindButton));
284323b6546SOliver Tappe #endif
285323b6546SOliver Tappe 	item->SetEnabled(!dragging);
286323b6546SOliver Tappe 	AddItem(item);
287323b6546SOliver Tappe 
288323b6546SOliver Tappe 	item = new BMenuItem(B_TRANSLATE("Show replicants"),
289323b6546SOliver Tappe 		new BMessage(kToggleDraggers));
290323b6546SOliver Tappe 	item->SetEnabled(!dragging);
291323b6546SOliver Tappe 	item->SetMarked(BDragger::AreDraggersDrawn());
292323b6546SOliver Tappe 	AddItem(item);
293323b6546SOliver Tappe 
294323b6546SOliver Tappe 	static const char* kMountMenuStr = B_TRANSLATE_MARK("Mount");
295323b6546SOliver Tappe 
296323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR
297323b6546SOliver Tappe 	DeskbarMountMenu* mountMenu = new DeskbarMountMenu(
298323b6546SOliver Tappe 		B_TRANSLATE_NOCOLLECT(kMountMenuStr));
299323b6546SOliver Tappe 	mountMenu->SetEnabled(!dragging);
300323b6546SOliver Tappe 	AddItem(mountMenu);
301323b6546SOliver Tappe #endif
302323b6546SOliver Tappe 
303323b6546SOliver Tappe 	item = new BMenuItem(B_TRANSLATE("Deskbar preferences" B_UTF8_ELLIPSIS),
304323b6546SOliver Tappe 		new BMessage(kConfigShow));
305323b6546SOliver Tappe 	item->SetTarget(be_app);
306323b6546SOliver Tappe 	AddItem(item);
307323b6546SOliver Tappe 
308323b6546SOliver Tappe 	AddSeparatorItem();
309323b6546SOliver Tappe 
310323b6546SOliver Tappe 	BMenu* shutdownMenu = new BMenu(B_TRANSLATE("Shutdown" B_UTF8_ELLIPSIS));
311323b6546SOliver Tappe 
312323b6546SOliver Tappe 	item = new BMenuItem(B_TRANSLATE("Restart system"),
313323b6546SOliver Tappe 		new BMessage(kRebootSystem));
314323b6546SOliver Tappe 	item->SetEnabled(!dragging);
315323b6546SOliver Tappe 	shutdownMenu->AddItem(item);
316323b6546SOliver Tappe 
317323b6546SOliver Tappe #if defined(APM_SUPPORT) || defined(B_COLLECTING_CATKEYS)
318323b6546SOliver Tappe 	static const char* kSuspendMenuItemStr = B_TRANSLATE_MARK("Suspend");
319323b6546SOliver Tappe #endif
320323b6546SOliver Tappe 
321323b6546SOliver Tappe #ifdef APM_SUPPORT
322323b6546SOliver Tappe 	if (_kapm_control_(APM_CHECK_ENABLED) == B_OK) {
323323b6546SOliver Tappe 		item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kSuspendMenuItemStr),
324323b6546SOliver Tappe 			new BMessage(kSuspendSystem));
325323b6546SOliver Tappe 		item->SetEnabled(!dragging);
326323b6546SOliver Tappe 		shutdownMenu->AddItem(item);
327323b6546SOliver Tappe 	}
328323b6546SOliver Tappe #endif
329323b6546SOliver Tappe 
330323b6546SOliver Tappe 	item = new BMenuItem(B_TRANSLATE("Power off"),
331323b6546SOliver Tappe 		new BMessage(kShutdownSystem));
332323b6546SOliver Tappe 	item->SetEnabled(!dragging);
333323b6546SOliver Tappe 	shutdownMenu->AddItem(item);
334323b6546SOliver Tappe 	shutdownMenu->SetFont(be_plain_font);
335323b6546SOliver Tappe 
336323b6546SOliver Tappe 	shutdownMenu->SetTargetForItems(be_app);
337323b6546SOliver Tappe 	BMessage* message = new BMessage(kShutdownSystem);
338323b6546SOliver Tappe 	message->AddBool("confirm", true);
339323b6546SOliver Tappe 	AddItem(new BMenuItem(shutdownMenu, message));
340323b6546SOliver Tappe 
341323b6546SOliver Tappe 	fAddState = kAddingRecents;
342323b6546SOliver Tappe 
343323b6546SOliver Tappe 	return true;
344323b6546SOliver Tappe }
345323b6546SOliver Tappe 
346323b6546SOliver Tappe 
347323b6546SOliver Tappe void
348323b6546SOliver Tappe TDeskbarMenu::ClearMenuBuildingState()
349323b6546SOliver Tappe {
350323b6546SOliver Tappe 	fAddState = kDone;
351323b6546SOliver Tappe 	fMenuBuilt = false;
352323b6546SOliver Tappe 		// force the menu to get rebuilt each time
353323b6546SOliver Tappe 	BNavMenu::ClearMenuBuildingState();
354323b6546SOliver Tappe }
355323b6546SOliver Tappe 
356323b6546SOliver Tappe 
357323b6546SOliver Tappe void
358323b6546SOliver Tappe TDeskbarMenu::ResetTargets()
359323b6546SOliver Tappe {
360323b6546SOliver Tappe 	// This method does not recurse into submenus
361323b6546SOliver Tappe 	// and does not affect menu items in submenus.
362323b6546SOliver Tappe 	// (e.g. "Restart System" and "Power Off")
363323b6546SOliver Tappe 
364323b6546SOliver Tappe 	BNavMenu::ResetTargets();
365323b6546SOliver Tappe 
366323b6546SOliver Tappe 	// if we are dragging, set the target to whatever was set
367323b6546SOliver Tappe 	// else set it to the default (Tracker)
368323b6546SOliver Tappe 	if (!fBarView->Dragging())
369323b6546SOliver Tappe 		SetTarget(DefaultTarget());
370323b6546SOliver Tappe 
371323b6546SOliver Tappe 	// now set the target for the menuitems to the currently
372323b6546SOliver Tappe 	// set target, which may or may not be tracker
373323b6546SOliver Tappe 	SetTargetForItems(Target());
374323b6546SOliver Tappe 
375323b6546SOliver Tappe 	for (int32 i = 0; ; i++) {
376323b6546SOliver Tappe 		BMenuItem* item = ItemAt(i);
377323b6546SOliver Tappe 		if (item == NULL)
378323b6546SOliver Tappe 			break;
379323b6546SOliver Tappe 
380323b6546SOliver Tappe 		if (item->Message()) {
381323b6546SOliver Tappe 			switch (item->Message()->what) {
382323b6546SOliver Tappe 				case kFindButton:
383323b6546SOliver Tappe 					item->SetTarget(BMessenger(kTrackerSignature));
384323b6546SOliver Tappe 					break;
385323b6546SOliver Tappe 
386323b6546SOliver Tappe 				case kShowSplash:
387323b6546SOliver Tappe 				case kToggleDraggers:
388323b6546SOliver Tappe 				case kConfigShow:
389323b6546SOliver Tappe 				case kAlwaysTop:
390*573f748cSJohn Scipione 				case kExpandNewTeams:
391*573f748cSJohn Scipione 				case kHideLabels:
392*573f748cSJohn Scipione 				case kResizeTeamIcons:
393*573f748cSJohn Scipione 				case kSortRunningApps:
394*573f748cSJohn Scipione 				case kTrackerFirst:
395323b6546SOliver Tappe 				case kRebootSystem:
396323b6546SOliver Tappe 				case kSuspendSystem:
397323b6546SOliver Tappe 				case kShutdownSystem:
398323b6546SOliver Tappe 					item->SetTarget(be_app);
399323b6546SOliver Tappe 					break;
400*573f748cSJohn Scipione 
401*573f748cSJohn Scipione 				case kShowHideTime:
402*573f748cSJohn Scipione 				case kTimeIntervalChanged:
403*573f748cSJohn Scipione 				case kTimeFormatChanged:
404*573f748cSJohn Scipione 					item->SetTarget(fBarView->fReplicantTray);
405*573f748cSJohn Scipione 					break;
406323b6546SOliver Tappe 			}
407323b6546SOliver Tappe 		}
408323b6546SOliver Tappe 	}
409323b6546SOliver Tappe }
410323b6546SOliver Tappe 
411323b6546SOliver Tappe 
412323b6546SOliver Tappe BPoint
413323b6546SOliver Tappe TDeskbarMenu::ScreenLocation()
414323b6546SOliver Tappe {
415323b6546SOliver Tappe 	bool vertical = fBarView->Vertical();
416323b6546SOliver Tappe 	int32 expando = (fBarView->State() == kExpandoState);
417323b6546SOliver Tappe 	BPoint point;
418323b6546SOliver Tappe 
419323b6546SOliver Tappe 	BRect rect = Supermenu()->Bounds();
420323b6546SOliver Tappe 	Supermenu()->ConvertToScreen(&rect);
421323b6546SOliver Tappe 
422323b6546SOliver Tappe 	if (expando && vertical && fBarView->Left()) {
423323b6546SOliver Tappe 		PRINT(("Left\n"));
424323b6546SOliver Tappe 		point = rect.RightTop() + BPoint(0, 3);
425323b6546SOliver Tappe 	} else if (expando && vertical && !fBarView->Left()) {
426323b6546SOliver Tappe 		PRINT(("Right\n"));
427323b6546SOliver Tappe 		point = rect.LeftTop() - BPoint(Bounds().Width(), 0) + BPoint(0, 3);
428323b6546SOliver Tappe 	} else
429323b6546SOliver Tappe 		point = BMenu::ScreenLocation();
430323b6546SOliver Tappe 
431323b6546SOliver Tappe 	return point;
432323b6546SOliver Tappe }
433323b6546SOliver Tappe 
434323b6546SOliver Tappe 
435323b6546SOliver Tappe /*static*/
436323b6546SOliver Tappe BMessenger
437323b6546SOliver Tappe TDeskbarMenu::DefaultTarget()
438323b6546SOliver Tappe {
439323b6546SOliver Tappe 	// if Tracker is not available we target the BarApp
440323b6546SOliver Tappe 	BMessenger target(kTrackerSignature);
441323b6546SOliver Tappe 	if (target.IsValid())
442323b6546SOliver Tappe 		return target;
443323b6546SOliver Tappe 
444323b6546SOliver Tappe 	return BMessenger(be_app);
445323b6546SOliver Tappe }
446323b6546SOliver Tappe 
447323b6546SOliver Tappe 
448323b6546SOliver Tappe //	#pragma mark -
449323b6546SOliver Tappe 
450323b6546SOliver Tappe 
451323b6546SOliver Tappe TRecentsMenu::TRecentsMenu(const char* name, TBarView* bar, int32 which,
452323b6546SOliver Tappe 		const char* signature, entry_ref* appRef)
453323b6546SOliver Tappe 	: BNavMenu(name, B_REFS_RECEIVED, TDeskbarMenu::DefaultTarget()),
454323b6546SOliver Tappe 	fWhich(which),
455323b6546SOliver Tappe 	fAppRef(NULL),
456323b6546SOliver Tappe 	fSignature(NULL),
457323b6546SOliver Tappe 	fRecentsCount(0),
458323b6546SOliver Tappe 	fRecentsEnabled(false),
459323b6546SOliver Tappe 	fItemIndex(0),
460323b6546SOliver Tappe 	fBarView(bar)
461323b6546SOliver Tappe {
462323b6546SOliver Tappe 	TBarApp* app = dynamic_cast<TBarApp*>(be_app);
463323b6546SOliver Tappe 	if (app == NULL)
464323b6546SOliver Tappe 		return;
465323b6546SOliver Tappe 
466323b6546SOliver Tappe 	switch (which) {
467323b6546SOliver Tappe 		case kRecentDocuments:
468323b6546SOliver Tappe 			fRecentsCount = app->Settings()->recentDocsCount;
469323b6546SOliver Tappe 			fRecentsEnabled = app->Settings()->recentDocsEnabled;
470323b6546SOliver Tappe 			break;
471323b6546SOliver Tappe 		case kRecentApplications:
472323b6546SOliver Tappe 			fRecentsCount = app->Settings()->recentAppsCount;
473323b6546SOliver Tappe 			fRecentsEnabled = app->Settings()->recentAppsEnabled;
474323b6546SOliver Tappe 			break;
475323b6546SOliver Tappe 		case kRecentAppDocuments:
476323b6546SOliver Tappe 			fRecentsCount = app->Settings()->recentDocsCount;
477323b6546SOliver Tappe 			fRecentsEnabled = app->Settings()->recentDocsEnabled;
478323b6546SOliver Tappe 			if (signature != NULL)
479323b6546SOliver Tappe 				fSignature = strdup(signature);
480323b6546SOliver Tappe 			if (appRef != NULL)
481323b6546SOliver Tappe 				fAppRef = new entry_ref(*appRef);
482323b6546SOliver Tappe 			break;
483323b6546SOliver Tappe 		case kRecentFolders:
484323b6546SOliver Tappe 			fRecentsCount = app->Settings()->recentFoldersCount;
485323b6546SOliver Tappe 			fRecentsEnabled = app->Settings()->recentFoldersEnabled;
486323b6546SOliver Tappe 			break;
487323b6546SOliver Tappe 	}
488323b6546SOliver Tappe }
489323b6546SOliver Tappe 
490323b6546SOliver Tappe 
491323b6546SOliver Tappe TRecentsMenu::~TRecentsMenu()
492323b6546SOliver Tappe {
493323b6546SOliver Tappe 	delete fAppRef;
494323b6546SOliver Tappe 	free(fSignature);
495323b6546SOliver Tappe }
496323b6546SOliver Tappe 
497323b6546SOliver Tappe 
498323b6546SOliver Tappe void
499323b6546SOliver Tappe TRecentsMenu::DetachedFromWindow()
500323b6546SOliver Tappe {
501323b6546SOliver Tappe 	// BNavMenu::DetachedFromWindow sets the TypesList to NULL
502323b6546SOliver Tappe 	BMenu::DetachedFromWindow();
503323b6546SOliver Tappe }
504323b6546SOliver Tappe 
505323b6546SOliver Tappe 
506323b6546SOliver Tappe bool
507323b6546SOliver Tappe TRecentsMenu::StartBuildingItemList()
508323b6546SOliver Tappe {
509323b6546SOliver Tappe 	RemoveItems(0, CountItems(), true);
510323b6546SOliver Tappe 
511323b6546SOliver Tappe 	// !! note: don't call inherited from here
512323b6546SOliver Tappe 	// the navref is not set for this menu
513323b6546SOliver Tappe 	// but it still needs to be a draggable navmenu
514323b6546SOliver Tappe 	// simply return true so that AddNextItem is called
515323b6546SOliver Tappe 	//
516323b6546SOliver Tappe 	// return BNavMenu::StartBuildingItemList();
517323b6546SOliver Tappe 	return true;
518323b6546SOliver Tappe }
519323b6546SOliver Tappe 
520323b6546SOliver Tappe 
521323b6546SOliver Tappe bool
522323b6546SOliver Tappe TRecentsMenu::AddNextItem()
523323b6546SOliver Tappe {
524323b6546SOliver Tappe 	if (fRecentsCount > 0 && fRecentsEnabled && AddRecents(fRecentsCount))
525323b6546SOliver Tappe 		return true;
526323b6546SOliver Tappe 
527323b6546SOliver Tappe 	fItemIndex = 0;
528323b6546SOliver Tappe 	return false;
529323b6546SOliver Tappe }
530323b6546SOliver Tappe 
531323b6546SOliver Tappe 
532323b6546SOliver Tappe bool
533323b6546SOliver Tappe TRecentsMenu::AddRecents(int32 count)
534323b6546SOliver Tappe {
535323b6546SOliver Tappe 	if (fItemIndex == 0) {
536323b6546SOliver Tappe 		fRecentList.MakeEmpty();
537323b6546SOliver Tappe 		BRoster roster;
538323b6546SOliver Tappe 
539323b6546SOliver Tappe 		switch (fWhich) {
540323b6546SOliver Tappe 			case kRecentDocuments:
541323b6546SOliver Tappe 				roster.GetRecentDocuments(&fRecentList, count);
542323b6546SOliver Tappe 				break;
543323b6546SOliver Tappe 			case kRecentApplications:
544323b6546SOliver Tappe 				roster.GetRecentApps(&fRecentList, count);
545323b6546SOliver Tappe 				break;
546323b6546SOliver Tappe 			case kRecentAppDocuments:
547323b6546SOliver Tappe 				roster.GetRecentDocuments(&fRecentList, count, NULL,
548323b6546SOliver Tappe 					fSignature);
549323b6546SOliver Tappe 				break;
550323b6546SOliver Tappe 			case kRecentFolders:
551323b6546SOliver Tappe 				roster.GetRecentFolders(&fRecentList, count);
552323b6546SOliver Tappe 				break;
553323b6546SOliver Tappe 			default:
554323b6546SOliver Tappe 				return false;
555323b6546SOliver Tappe 		}
556323b6546SOliver Tappe 	}
557323b6546SOliver Tappe 
558323b6546SOliver Tappe 	for (;;) {
559323b6546SOliver Tappe 		entry_ref ref;
560323b6546SOliver Tappe 		if (fRecentList.FindRef("refs", fItemIndex++, &ref) != B_OK)
561323b6546SOliver Tappe 			break;
562323b6546SOliver Tappe 
563323b6546SOliver Tappe 		if (ref.name && strlen(ref.name) > 0) {
564323b6546SOliver Tappe 			Model model(&ref, true);
565323b6546SOliver Tappe 
566323b6546SOliver Tappe 			if (fWhich != kRecentApplications) {
567323b6546SOliver Tappe 				BMessage* message = new BMessage(B_REFS_RECEIVED);
568323b6546SOliver Tappe 				if (fWhich == kRecentAppDocuments) {
569323b6546SOliver Tappe 					// add application as handler
570323b6546SOliver Tappe 					message->AddRef("handler", fAppRef);
571323b6546SOliver Tappe 				}
572323b6546SOliver Tappe 
573323b6546SOliver Tappe 				ModelMenuItem* item = BNavMenu::NewModelItem(&model,
574323b6546SOliver Tappe 					message, Target(), false, NULL, TypesList());
575323b6546SOliver Tappe 
576323b6546SOliver Tappe 				if (item)
577323b6546SOliver Tappe 					AddItem(item);
578323b6546SOliver Tappe 			} else {
579323b6546SOliver Tappe 				// The application items expand to a list of recent documents
580323b6546SOliver Tappe 				// for that application - so they must be handled extra
581323b6546SOliver Tappe 				BFile file(&ref, B_READ_ONLY);
582323b6546SOliver Tappe 				char signature[B_MIME_TYPE_LENGTH];
583323b6546SOliver Tappe 
584323b6546SOliver Tappe 				BAppFileInfo appInfo(&file);
585323b6546SOliver Tappe 				if (appInfo.InitCheck() != B_OK
586323b6546SOliver Tappe 					|| appInfo.GetSignature(signature) != B_OK)
587323b6546SOliver Tappe 					continue;
588323b6546SOliver Tappe 
589323b6546SOliver Tappe 				ModelMenuItem* item = NULL;
590323b6546SOliver Tappe 				BMessage doc;
591323b6546SOliver Tappe 				be_roster->GetRecentDocuments(&doc, 1, NULL, signature);
592323b6546SOliver Tappe 					// ToDo: check if the documents do exist at all to
593323b6546SOliver Tappe 					//		avoid the creation of the submenu.
594323b6546SOliver Tappe 
595323b6546SOliver Tappe 				if (doc.CountNames(B_REF_TYPE) > 0) {
596323b6546SOliver Tappe 					// create recents menu that will contain the recent docs of
597323b6546SOliver Tappe 					// this app
598323b6546SOliver Tappe 					TRecentsMenu* docs = new TRecentsMenu(model.Name(),
599323b6546SOliver Tappe 						fBarView, kRecentAppDocuments, signature, &ref);
600323b6546SOliver Tappe 					docs->SetTypesList(TypesList());
601323b6546SOliver Tappe 					docs->SetTarget(Target());
602323b6546SOliver Tappe 
603323b6546SOliver Tappe 					item = new ModelMenuItem(&model, docs);
604323b6546SOliver Tappe 				} else
605323b6546SOliver Tappe 					item = new ModelMenuItem(&model, model.Name(), NULL);
606323b6546SOliver Tappe 
607323b6546SOliver Tappe 				if (item) {
608323b6546SOliver Tappe 					// add refs-message so that the recent app can be launched
609323b6546SOliver Tappe 					BMessage* msg = new BMessage(B_REFS_RECEIVED);
610323b6546SOliver Tappe 					msg->AddRef("refs", &ref);
611323b6546SOliver Tappe 					item->SetMessage(msg);
612323b6546SOliver Tappe 					item->SetTarget(Target());
613323b6546SOliver Tappe 
614323b6546SOliver Tappe 					AddItem(item);
615323b6546SOliver Tappe 				}
616323b6546SOliver Tappe 			}
617323b6546SOliver Tappe 
618323b6546SOliver Tappe 			// return true so that we know to reenter this list
619323b6546SOliver Tappe 			return true;
620323b6546SOliver Tappe 		}
621323b6546SOliver Tappe 	}
622323b6546SOliver Tappe 
623323b6546SOliver Tappe 	// return false if we are done with this list
624323b6546SOliver Tappe 	return false;
625323b6546SOliver Tappe }
626323b6546SOliver Tappe 
627323b6546SOliver Tappe 
628323b6546SOliver Tappe void
629323b6546SOliver Tappe TRecentsMenu::DoneBuildingItemList()
630323b6546SOliver Tappe {
631323b6546SOliver Tappe 	// !! note: don't call inherited here
632323b6546SOliver Tappe 	// the object list is not built
633323b6546SOliver Tappe 	// and this list does not need to be sorted
634323b6546SOliver Tappe 	// BNavMenu::DoneBuildingItemList();
635323b6546SOliver Tappe 
636323b6546SOliver Tappe 	if (CountItems() > 0)
637323b6546SOliver Tappe 		SetTargetForItems(Target());
638323b6546SOliver Tappe }
639323b6546SOliver Tappe 
640323b6546SOliver Tappe 
641323b6546SOliver Tappe void
642323b6546SOliver Tappe TRecentsMenu::ClearMenuBuildingState()
643323b6546SOliver Tappe {
644323b6546SOliver Tappe 	fMenuBuilt = false;
645323b6546SOliver Tappe 	BNavMenu::ClearMenuBuildingState();
646323b6546SOliver Tappe }
647323b6546SOliver Tappe 
648323b6546SOliver Tappe 
649323b6546SOliver Tappe void
650323b6546SOliver Tappe TRecentsMenu::ResetTargets()
651323b6546SOliver Tappe {
652323b6546SOliver Tappe 	BNavMenu::ResetTargets();
653323b6546SOliver Tappe 
654323b6546SOliver Tappe 	// if we are dragging, set the target to whatever was set
655323b6546SOliver Tappe 	// else set it to the default (Tracker)
656323b6546SOliver Tappe 	if (!fBarView->Dragging())
657323b6546SOliver Tappe 		SetTarget(TDeskbarMenu::DefaultTarget());
658323b6546SOliver Tappe 
659323b6546SOliver Tappe 	// now set the target for the menuitems to the currently
660323b6546SOliver Tappe 	// set target, which may or may not be tracker
661323b6546SOliver Tappe 	SetTargetForItems(Target());
662323b6546SOliver Tappe }
663323b6546SOliver Tappe 
664323b6546SOliver Tappe 
665323b6546SOliver Tappe //*****************************************************************************
666323b6546SOliver Tappe //	#pragma mark -
667323b6546SOliver Tappe 
668323b6546SOliver Tappe 
669323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR
670323b6546SOliver Tappe 
671323b6546SOliver Tappe DeskbarMountMenu::DeskbarMountMenu(const char* name)
672323b6546SOliver Tappe 	: BPrivate::MountMenu(name)
673323b6546SOliver Tappe {
674323b6546SOliver Tappe 	SetFont(be_plain_font);
675323b6546SOliver Tappe }
676323b6546SOliver Tappe 
677323b6546SOliver Tappe 
678323b6546SOliver Tappe bool
679323b6546SOliver Tappe DeskbarMountMenu::AddDynamicItem(add_state s)
680323b6546SOliver Tappe {
681323b6546SOliver Tappe 	BPrivate::MountMenu::AddDynamicItem(s);
682323b6546SOliver Tappe 
683323b6546SOliver Tappe 	SetTargetForItems(BMessenger(kTrackerSignature));
684323b6546SOliver Tappe 
685323b6546SOliver Tappe 	return false;
686323b6546SOliver Tappe }
687323b6546SOliver Tappe 
688323b6546SOliver Tappe 
689323b6546SOliver Tappe #endif
690323b6546SOliver Tappe 
691