xref: /haiku/src/apps/deskbar/DeskbarMenu.cpp (revision 546208a53940a26c6379c48a7854ade1a8250fc5)
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 
60*546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
61*546208a5SOliver Tappe #define B_TRANSLATION_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:
390573f748cSJohn Scipione 				case kExpandNewTeams:
391573f748cSJohn Scipione 				case kHideLabels:
392573f748cSJohn Scipione 				case kResizeTeamIcons:
393573f748cSJohn Scipione 				case kSortRunningApps:
394573f748cSJohn Scipione 				case kTrackerFirst:
395323b6546SOliver Tappe 				case kRebootSystem:
396323b6546SOliver Tappe 				case kSuspendSystem:
397323b6546SOliver Tappe 				case kShutdownSystem:
398323b6546SOliver Tappe 					item->SetTarget(be_app);
399323b6546SOliver Tappe 					break;
400573f748cSJohn Scipione 
401573f748cSJohn Scipione 				case kShowHideTime:
402573f748cSJohn Scipione 				case kTimeIntervalChanged:
4033cf2d117SJohn Scipione 				case kShowSeconds:
4043cf2d117SJohn Scipione 				case kShowDayOfWeek:
4053cf2d117SJohn Scipione 				case kShowTimeZone:
406573f748cSJohn Scipione 					item->SetTarget(fBarView->fReplicantTray);
407573f748cSJohn Scipione 					break;
408323b6546SOliver Tappe 			}
409323b6546SOliver Tappe 		}
410323b6546SOliver Tappe 	}
411323b6546SOliver Tappe }
412323b6546SOliver Tappe 
413323b6546SOliver Tappe 
414323b6546SOliver Tappe BPoint
415323b6546SOliver Tappe TDeskbarMenu::ScreenLocation()
416323b6546SOliver Tappe {
417323b6546SOliver Tappe 	bool vertical = fBarView->Vertical();
418323b6546SOliver Tappe 	int32 expando = (fBarView->State() == kExpandoState);
419323b6546SOliver Tappe 	BPoint point;
420323b6546SOliver Tappe 
421323b6546SOliver Tappe 	BRect rect = Supermenu()->Bounds();
422323b6546SOliver Tappe 	Supermenu()->ConvertToScreen(&rect);
423323b6546SOliver Tappe 
424323b6546SOliver Tappe 	if (expando && vertical && fBarView->Left()) {
425323b6546SOliver Tappe 		PRINT(("Left\n"));
426323b6546SOliver Tappe 		point = rect.RightTop() + BPoint(0, 3);
427323b6546SOliver Tappe 	} else if (expando && vertical && !fBarView->Left()) {
428323b6546SOliver Tappe 		PRINT(("Right\n"));
429323b6546SOliver Tappe 		point = rect.LeftTop() - BPoint(Bounds().Width(), 0) + BPoint(0, 3);
430323b6546SOliver Tappe 	} else
431323b6546SOliver Tappe 		point = BMenu::ScreenLocation();
432323b6546SOliver Tappe 
433323b6546SOliver Tappe 	return point;
434323b6546SOliver Tappe }
435323b6546SOliver Tappe 
436323b6546SOliver Tappe 
437323b6546SOliver Tappe /*static*/
438323b6546SOliver Tappe BMessenger
439323b6546SOliver Tappe TDeskbarMenu::DefaultTarget()
440323b6546SOliver Tappe {
441323b6546SOliver Tappe 	// if Tracker is not available we target the BarApp
442323b6546SOliver Tappe 	BMessenger target(kTrackerSignature);
443323b6546SOliver Tappe 	if (target.IsValid())
444323b6546SOliver Tappe 		return target;
445323b6546SOliver Tappe 
446323b6546SOliver Tappe 	return BMessenger(be_app);
447323b6546SOliver Tappe }
448323b6546SOliver Tappe 
449323b6546SOliver Tappe 
450323b6546SOliver Tappe //	#pragma mark -
451323b6546SOliver Tappe 
452323b6546SOliver Tappe 
453323b6546SOliver Tappe TRecentsMenu::TRecentsMenu(const char* name, TBarView* bar, int32 which,
454323b6546SOliver Tappe 		const char* signature, entry_ref* appRef)
455323b6546SOliver Tappe 	: BNavMenu(name, B_REFS_RECEIVED, TDeskbarMenu::DefaultTarget()),
456323b6546SOliver Tappe 	fWhich(which),
457323b6546SOliver Tappe 	fAppRef(NULL),
458323b6546SOliver Tappe 	fSignature(NULL),
459323b6546SOliver Tappe 	fRecentsCount(0),
460323b6546SOliver Tappe 	fRecentsEnabled(false),
461323b6546SOliver Tappe 	fItemIndex(0),
462323b6546SOliver Tappe 	fBarView(bar)
463323b6546SOliver Tappe {
464323b6546SOliver Tappe 	TBarApp* app = dynamic_cast<TBarApp*>(be_app);
465323b6546SOliver Tappe 	if (app == NULL)
466323b6546SOliver Tappe 		return;
467323b6546SOliver Tappe 
468323b6546SOliver Tappe 	switch (which) {
469323b6546SOliver Tappe 		case kRecentDocuments:
470323b6546SOliver Tappe 			fRecentsCount = app->Settings()->recentDocsCount;
471323b6546SOliver Tappe 			fRecentsEnabled = app->Settings()->recentDocsEnabled;
472323b6546SOliver Tappe 			break;
473323b6546SOliver Tappe 		case kRecentApplications:
474323b6546SOliver Tappe 			fRecentsCount = app->Settings()->recentAppsCount;
475323b6546SOliver Tappe 			fRecentsEnabled = app->Settings()->recentAppsEnabled;
476323b6546SOliver Tappe 			break;
477323b6546SOliver Tappe 		case kRecentAppDocuments:
478323b6546SOliver Tappe 			fRecentsCount = app->Settings()->recentDocsCount;
479323b6546SOliver Tappe 			fRecentsEnabled = app->Settings()->recentDocsEnabled;
480323b6546SOliver Tappe 			if (signature != NULL)
481323b6546SOliver Tappe 				fSignature = strdup(signature);
482323b6546SOliver Tappe 			if (appRef != NULL)
483323b6546SOliver Tappe 				fAppRef = new entry_ref(*appRef);
484323b6546SOliver Tappe 			break;
485323b6546SOliver Tappe 		case kRecentFolders:
486323b6546SOliver Tappe 			fRecentsCount = app->Settings()->recentFoldersCount;
487323b6546SOliver Tappe 			fRecentsEnabled = app->Settings()->recentFoldersEnabled;
488323b6546SOliver Tappe 			break;
489323b6546SOliver Tappe 	}
490323b6546SOliver Tappe }
491323b6546SOliver Tappe 
492323b6546SOliver Tappe 
493323b6546SOliver Tappe TRecentsMenu::~TRecentsMenu()
494323b6546SOliver Tappe {
495323b6546SOliver Tappe 	delete fAppRef;
496323b6546SOliver Tappe 	free(fSignature);
497323b6546SOliver Tappe }
498323b6546SOliver Tappe 
499323b6546SOliver Tappe 
500323b6546SOliver Tappe void
501323b6546SOliver Tappe TRecentsMenu::DetachedFromWindow()
502323b6546SOliver Tappe {
503323b6546SOliver Tappe 	// BNavMenu::DetachedFromWindow sets the TypesList to NULL
504323b6546SOliver Tappe 	BMenu::DetachedFromWindow();
505323b6546SOliver Tappe }
506323b6546SOliver Tappe 
507323b6546SOliver Tappe 
508323b6546SOliver Tappe bool
509323b6546SOliver Tappe TRecentsMenu::StartBuildingItemList()
510323b6546SOliver Tappe {
511323b6546SOliver Tappe 	RemoveItems(0, CountItems(), true);
512323b6546SOliver Tappe 
513323b6546SOliver Tappe 	// !! note: don't call inherited from here
514323b6546SOliver Tappe 	// the navref is not set for this menu
515323b6546SOliver Tappe 	// but it still needs to be a draggable navmenu
516323b6546SOliver Tappe 	// simply return true so that AddNextItem is called
517323b6546SOliver Tappe 	//
518323b6546SOliver Tappe 	// return BNavMenu::StartBuildingItemList();
519323b6546SOliver Tappe 	return true;
520323b6546SOliver Tappe }
521323b6546SOliver Tappe 
522323b6546SOliver Tappe 
523323b6546SOliver Tappe bool
524323b6546SOliver Tappe TRecentsMenu::AddNextItem()
525323b6546SOliver Tappe {
526323b6546SOliver Tappe 	if (fRecentsCount > 0 && fRecentsEnabled && AddRecents(fRecentsCount))
527323b6546SOliver Tappe 		return true;
528323b6546SOliver Tappe 
529323b6546SOliver Tappe 	fItemIndex = 0;
530323b6546SOliver Tappe 	return false;
531323b6546SOliver Tappe }
532323b6546SOliver Tappe 
533323b6546SOliver Tappe 
534323b6546SOliver Tappe bool
535323b6546SOliver Tappe TRecentsMenu::AddRecents(int32 count)
536323b6546SOliver Tappe {
537323b6546SOliver Tappe 	if (fItemIndex == 0) {
538323b6546SOliver Tappe 		fRecentList.MakeEmpty();
539323b6546SOliver Tappe 		BRoster roster;
540323b6546SOliver Tappe 
541323b6546SOliver Tappe 		switch (fWhich) {
542323b6546SOliver Tappe 			case kRecentDocuments:
543323b6546SOliver Tappe 				roster.GetRecentDocuments(&fRecentList, count);
544323b6546SOliver Tappe 				break;
545323b6546SOliver Tappe 			case kRecentApplications:
546323b6546SOliver Tappe 				roster.GetRecentApps(&fRecentList, count);
547323b6546SOliver Tappe 				break;
548323b6546SOliver Tappe 			case kRecentAppDocuments:
549323b6546SOliver Tappe 				roster.GetRecentDocuments(&fRecentList, count, NULL,
550323b6546SOliver Tappe 					fSignature);
551323b6546SOliver Tappe 				break;
552323b6546SOliver Tappe 			case kRecentFolders:
553323b6546SOliver Tappe 				roster.GetRecentFolders(&fRecentList, count);
554323b6546SOliver Tappe 				break;
555323b6546SOliver Tappe 			default:
556323b6546SOliver Tappe 				return false;
557323b6546SOliver Tappe 		}
558323b6546SOliver Tappe 	}
559323b6546SOliver Tappe 
560323b6546SOliver Tappe 	for (;;) {
561323b6546SOliver Tappe 		entry_ref ref;
562323b6546SOliver Tappe 		if (fRecentList.FindRef("refs", fItemIndex++, &ref) != B_OK)
563323b6546SOliver Tappe 			break;
564323b6546SOliver Tappe 
565323b6546SOliver Tappe 		if (ref.name && strlen(ref.name) > 0) {
566323b6546SOliver Tappe 			Model model(&ref, true);
567323b6546SOliver Tappe 
568323b6546SOliver Tappe 			if (fWhich != kRecentApplications) {
569323b6546SOliver Tappe 				BMessage* message = new BMessage(B_REFS_RECEIVED);
570323b6546SOliver Tappe 				if (fWhich == kRecentAppDocuments) {
571323b6546SOliver Tappe 					// add application as handler
572323b6546SOliver Tappe 					message->AddRef("handler", fAppRef);
573323b6546SOliver Tappe 				}
574323b6546SOliver Tappe 
575323b6546SOliver Tappe 				ModelMenuItem* item = BNavMenu::NewModelItem(&model,
576323b6546SOliver Tappe 					message, Target(), false, NULL, TypesList());
577323b6546SOliver Tappe 
578323b6546SOliver Tappe 				if (item)
579323b6546SOliver Tappe 					AddItem(item);
580323b6546SOliver Tappe 			} else {
581323b6546SOliver Tappe 				// The application items expand to a list of recent documents
582323b6546SOliver Tappe 				// for that application - so they must be handled extra
583323b6546SOliver Tappe 				BFile file(&ref, B_READ_ONLY);
584323b6546SOliver Tappe 				char signature[B_MIME_TYPE_LENGTH];
585323b6546SOliver Tappe 
586323b6546SOliver Tappe 				BAppFileInfo appInfo(&file);
587323b6546SOliver Tappe 				if (appInfo.InitCheck() != B_OK
588323b6546SOliver Tappe 					|| appInfo.GetSignature(signature) != B_OK)
589323b6546SOliver Tappe 					continue;
590323b6546SOliver Tappe 
591323b6546SOliver Tappe 				ModelMenuItem* item = NULL;
592323b6546SOliver Tappe 				BMessage doc;
593323b6546SOliver Tappe 				be_roster->GetRecentDocuments(&doc, 1, NULL, signature);
594323b6546SOliver Tappe 					// ToDo: check if the documents do exist at all to
595323b6546SOliver Tappe 					//		avoid the creation of the submenu.
596323b6546SOliver Tappe 
597323b6546SOliver Tappe 				if (doc.CountNames(B_REF_TYPE) > 0) {
598323b6546SOliver Tappe 					// create recents menu that will contain the recent docs of
599323b6546SOliver Tappe 					// this app
600323b6546SOliver Tappe 					TRecentsMenu* docs = new TRecentsMenu(model.Name(),
601323b6546SOliver Tappe 						fBarView, kRecentAppDocuments, signature, &ref);
602323b6546SOliver Tappe 					docs->SetTypesList(TypesList());
603323b6546SOliver Tappe 					docs->SetTarget(Target());
604323b6546SOliver Tappe 
605323b6546SOliver Tappe 					item = new ModelMenuItem(&model, docs);
606323b6546SOliver Tappe 				} else
607323b6546SOliver Tappe 					item = new ModelMenuItem(&model, model.Name(), NULL);
608323b6546SOliver Tappe 
609323b6546SOliver Tappe 				if (item) {
610323b6546SOliver Tappe 					// add refs-message so that the recent app can be launched
611323b6546SOliver Tappe 					BMessage* msg = new BMessage(B_REFS_RECEIVED);
612323b6546SOliver Tappe 					msg->AddRef("refs", &ref);
613323b6546SOliver Tappe 					item->SetMessage(msg);
614323b6546SOliver Tappe 					item->SetTarget(Target());
615323b6546SOliver Tappe 
616323b6546SOliver Tappe 					AddItem(item);
617323b6546SOliver Tappe 				}
618323b6546SOliver Tappe 			}
619323b6546SOliver Tappe 
620323b6546SOliver Tappe 			// return true so that we know to reenter this list
621323b6546SOliver Tappe 			return true;
622323b6546SOliver Tappe 		}
623323b6546SOliver Tappe 	}
624323b6546SOliver Tappe 
625323b6546SOliver Tappe 	// return false if we are done with this list
626323b6546SOliver Tappe 	return false;
627323b6546SOliver Tappe }
628323b6546SOliver Tappe 
629323b6546SOliver Tappe 
630323b6546SOliver Tappe void
631323b6546SOliver Tappe TRecentsMenu::DoneBuildingItemList()
632323b6546SOliver Tappe {
633323b6546SOliver Tappe 	// !! note: don't call inherited here
634323b6546SOliver Tappe 	// the object list is not built
635323b6546SOliver Tappe 	// and this list does not need to be sorted
636323b6546SOliver Tappe 	// BNavMenu::DoneBuildingItemList();
637323b6546SOliver Tappe 
638323b6546SOliver Tappe 	if (CountItems() > 0)
639323b6546SOliver Tappe 		SetTargetForItems(Target());
640323b6546SOliver Tappe }
641323b6546SOliver Tappe 
642323b6546SOliver Tappe 
643323b6546SOliver Tappe void
644323b6546SOliver Tappe TRecentsMenu::ClearMenuBuildingState()
645323b6546SOliver Tappe {
646323b6546SOliver Tappe 	fMenuBuilt = false;
647323b6546SOliver Tappe 	BNavMenu::ClearMenuBuildingState();
648323b6546SOliver Tappe }
649323b6546SOliver Tappe 
650323b6546SOliver Tappe 
651323b6546SOliver Tappe void
652323b6546SOliver Tappe TRecentsMenu::ResetTargets()
653323b6546SOliver Tappe {
654323b6546SOliver Tappe 	BNavMenu::ResetTargets();
655323b6546SOliver Tappe 
656323b6546SOliver Tappe 	// if we are dragging, set the target to whatever was set
657323b6546SOliver Tappe 	// else set it to the default (Tracker)
658323b6546SOliver Tappe 	if (!fBarView->Dragging())
659323b6546SOliver Tappe 		SetTarget(TDeskbarMenu::DefaultTarget());
660323b6546SOliver Tappe 
661323b6546SOliver Tappe 	// now set the target for the menuitems to the currently
662323b6546SOliver Tappe 	// set target, which may or may not be tracker
663323b6546SOliver Tappe 	SetTargetForItems(Target());
664323b6546SOliver Tappe }
665323b6546SOliver Tappe 
666323b6546SOliver Tappe 
667323b6546SOliver Tappe //*****************************************************************************
668323b6546SOliver Tappe //	#pragma mark -
669323b6546SOliver Tappe 
670323b6546SOliver Tappe 
671323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR
672323b6546SOliver Tappe 
673323b6546SOliver Tappe DeskbarMountMenu::DeskbarMountMenu(const char* name)
674323b6546SOliver Tappe 	: BPrivate::MountMenu(name)
675323b6546SOliver Tappe {
676323b6546SOliver Tappe 	SetFont(be_plain_font);
677323b6546SOliver Tappe }
678323b6546SOliver Tappe 
679323b6546SOliver Tappe 
680323b6546SOliver Tappe bool
681323b6546SOliver Tappe DeskbarMountMenu::AddDynamicItem(add_state s)
682323b6546SOliver Tappe {
683323b6546SOliver Tappe 	BPrivate::MountMenu::AddDynamicItem(s);
684323b6546SOliver Tappe 
685323b6546SOliver Tappe 	SetTargetForItems(BMessenger(kTrackerSignature));
686323b6546SOliver Tappe 
687323b6546SOliver Tappe 	return false;
688323b6546SOliver Tappe }
689323b6546SOliver Tappe 
690323b6546SOliver Tappe 
691323b6546SOliver Tappe #endif
692323b6546SOliver Tappe 
693