xref: /haiku/src/apps/deskbar/DeskbarMenu.cpp (revision 323b65468e5836bb27a5e373b14027d902349437)
1*323b6546SOliver Tappe /*
2*323b6546SOliver Tappe Open Tracker License
3*323b6546SOliver Tappe 
4*323b6546SOliver Tappe Terms and Conditions
5*323b6546SOliver Tappe 
6*323b6546SOliver Tappe Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7*323b6546SOliver Tappe 
8*323b6546SOliver Tappe Permission is hereby granted, free of charge, to any person obtaining a copy of
9*323b6546SOliver Tappe this software and associated documentation files (the "Software"), to deal in
10*323b6546SOliver Tappe the Software without restriction, including without limitation the rights to
11*323b6546SOliver Tappe use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12*323b6546SOliver Tappe of the Software, and to permit persons to whom the Software is furnished to do
13*323b6546SOliver Tappe so, subject to the following conditions:
14*323b6546SOliver Tappe 
15*323b6546SOliver Tappe The above copyright notice and this permission notice applies to all licensees
16*323b6546SOliver Tappe and shall be included in all copies or substantial portions of the Software.
17*323b6546SOliver Tappe 
18*323b6546SOliver Tappe THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19*323b6546SOliver Tappe IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20*323b6546SOliver Tappe FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21*323b6546SOliver Tappe BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22*323b6546SOliver Tappe AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23*323b6546SOliver Tappe WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24*323b6546SOliver Tappe 
25*323b6546SOliver Tappe Except as contained in this notice, the name of Be Incorporated shall not be
26*323b6546SOliver Tappe used in advertising or otherwise to promote the sale, use or other dealings in
27*323b6546SOliver Tappe this Software without prior written authorization from Be Incorporated.
28*323b6546SOliver Tappe 
29*323b6546SOliver Tappe Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered
30*323b6546SOliver Tappe trademarks of Be Incorporated in the United States and other countries. Other
31*323b6546SOliver Tappe brand product names are registered trademarks or trademarks of their respective
32*323b6546SOliver Tappe holders.
33*323b6546SOliver Tappe All rights reserved.
34*323b6546SOliver Tappe */
35*323b6546SOliver Tappe 
36*323b6546SOliver Tappe #include <Debug.h>
37*323b6546SOliver Tappe #include <Bitmap.h>
38*323b6546SOliver Tappe #include <Catalog.h>
39*323b6546SOliver Tappe #include <Dragger.h>
40*323b6546SOliver Tappe #include <Locale.h>
41*323b6546SOliver Tappe #include <Menu.h>
42*323b6546SOliver Tappe #include <MenuItem.h>
43*323b6546SOliver Tappe #include <Roster.h>
44*323b6546SOliver Tappe 
45*323b6546SOliver Tappe #include "DeskbarMenu.h"
46*323b6546SOliver Tappe #include "BarApp.h"
47*323b6546SOliver Tappe #include "BarView.h"
48*323b6546SOliver Tappe #include "DeskbarUtils.h"
49*323b6546SOliver Tappe #include "IconMenuItem.h"
50*323b6546SOliver Tappe #include "MountMenu.h"
51*323b6546SOliver Tappe #include "IconMenuItem.h"
52*323b6546SOliver Tappe #include "MountMenu.h"
53*323b6546SOliver Tappe #include "IconMenuItem.h"
54*323b6546SOliver Tappe #include "MountMenu.h"
55*323b6546SOliver Tappe #include "PublicCommands.h"
56*323b6546SOliver Tappe #include "RecentItems.h"
57*323b6546SOliver Tappe #include "StatusView.h"
58*323b6546SOliver Tappe #include "tracker_private.h"
59*323b6546SOliver Tappe 
60*323b6546SOliver Tappe #undef B_TRANSLATE_CONTEXT
61*323b6546SOliver Tappe #define B_TRANSLATE_CONTEXT "DeskbarMenu"
62*323b6546SOliver Tappe 
63*323b6546SOliver Tappe #define ROSTER_SIG "application/x-vnd.Be-ROST"
64*323b6546SOliver Tappe 
65*323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR
66*323b6546SOliver Tappe 
67*323b6546SOliver Tappe class DeskbarMountMenu : public BPrivate::MountMenu {
68*323b6546SOliver Tappe 	public:
69*323b6546SOliver Tappe 		DeskbarMountMenu(const char* name);
70*323b6546SOliver Tappe 		virtual bool AddDynamicItem(add_state s);
71*323b6546SOliver Tappe };
72*323b6546SOliver Tappe 
73*323b6546SOliver Tappe #endif
74*323b6546SOliver Tappe 
75*323b6546SOliver Tappe // #define SHOW_RECENT_FIND_ITEMS
76*323b6546SOliver Tappe 
77*323b6546SOliver Tappe namespace BPrivate {
78*323b6546SOliver Tappe 	BMenu* TrackerBuildRecentFindItemsMenu(const char*);
79*323b6546SOliver Tappe }
80*323b6546SOliver Tappe 
81*323b6546SOliver Tappe 
82*323b6546SOliver Tappe using namespace BPrivate;
83*323b6546SOliver Tappe 
84*323b6546SOliver Tappe 
85*323b6546SOliver Tappe //	#pragma mark -
86*323b6546SOliver Tappe 
87*323b6546SOliver Tappe 
88*323b6546SOliver Tappe TDeskbarMenu::TDeskbarMenu(TBarView* barView)
89*323b6546SOliver Tappe 	: BNavMenu("DeskbarMenu", B_REFS_RECEIVED, DefaultTarget()),
90*323b6546SOliver Tappe 	fAddState(kStart),
91*323b6546SOliver Tappe 	fBarView(barView)
92*323b6546SOliver Tappe {
93*323b6546SOliver Tappe }
94*323b6546SOliver Tappe 
95*323b6546SOliver Tappe 
96*323b6546SOliver Tappe void
97*323b6546SOliver Tappe TDeskbarMenu::AttachedToWindow()
98*323b6546SOliver Tappe {
99*323b6546SOliver Tappe 	if (fBarView && fBarView->LockLooper()) {
100*323b6546SOliver Tappe 		if (fBarView->Dragging()) {
101*323b6546SOliver Tappe 			SetTypesList(fBarView->CachedTypesList());
102*323b6546SOliver Tappe 			SetTarget(BMessenger(fBarView));
103*323b6546SOliver Tappe 			SetTrackingHookDeep(this, fBarView->MenuTrackingHook,
104*323b6546SOliver Tappe 				fBarView->GetTrackingHookData());
105*323b6546SOliver Tappe 			fBarView->DragStart();
106*323b6546SOliver Tappe 		} else {
107*323b6546SOliver Tappe 			SetTypesList(NULL);
108*323b6546SOliver Tappe 			SetTarget(DefaultTarget());
109*323b6546SOliver Tappe 			SetTrackingHookDeep(this, NULL, NULL);
110*323b6546SOliver Tappe 		}
111*323b6546SOliver Tappe 
112*323b6546SOliver Tappe 		fBarView->UnlockLooper();
113*323b6546SOliver Tappe 	}
114*323b6546SOliver Tappe 
115*323b6546SOliver Tappe 	BNavMenu::AttachedToWindow();
116*323b6546SOliver Tappe }
117*323b6546SOliver Tappe 
118*323b6546SOliver Tappe 
119*323b6546SOliver Tappe void
120*323b6546SOliver Tappe TDeskbarMenu::DetachedFromWindow()
121*323b6546SOliver Tappe {
122*323b6546SOliver Tappe 	if (fBarView) {
123*323b6546SOliver Tappe 		BLooper* looper = fBarView->Looper();
124*323b6546SOliver Tappe 		if (looper && looper->Lock()) {
125*323b6546SOliver Tappe 			fBarView->DragStop();
126*323b6546SOliver Tappe 			looper->Unlock();
127*323b6546SOliver Tappe 		}
128*323b6546SOliver Tappe 	}
129*323b6546SOliver Tappe 
130*323b6546SOliver Tappe 	// don't call BNavMenu::DetachedFromWindow
131*323b6546SOliver Tappe 	// it sets the TypesList to NULL
132*323b6546SOliver Tappe 	BMenu::DetachedFromWindow();
133*323b6546SOliver Tappe }
134*323b6546SOliver Tappe 
135*323b6546SOliver Tappe 
136*323b6546SOliver Tappe bool
137*323b6546SOliver Tappe TDeskbarMenu::StartBuildingItemList()
138*323b6546SOliver Tappe {
139*323b6546SOliver Tappe 	RemoveItems(0, CountItems(), true);
140*323b6546SOliver Tappe 	fAddState = kStart;
141*323b6546SOliver Tappe 	return BNavMenu::StartBuildingItemList();
142*323b6546SOliver Tappe }
143*323b6546SOliver Tappe 
144*323b6546SOliver Tappe 
145*323b6546SOliver Tappe void
146*323b6546SOliver Tappe TDeskbarMenu::DoneBuildingItemList()
147*323b6546SOliver Tappe {
148*323b6546SOliver Tappe 	if (fItemList->CountItems() <= 0) {
149*323b6546SOliver Tappe 		BMenuItem* item
150*323b6546SOliver Tappe 			= new BMenuItem(B_TRANSLATE("<Deskbar folder is empty>"), 0);
151*323b6546SOliver Tappe 		item->SetEnabled(false);
152*323b6546SOliver Tappe 		AddItem(item);
153*323b6546SOliver Tappe 	} else
154*323b6546SOliver Tappe 		BNavMenu::DoneBuildingItemList();
155*323b6546SOliver Tappe }
156*323b6546SOliver Tappe 
157*323b6546SOliver Tappe 
158*323b6546SOliver Tappe bool
159*323b6546SOliver Tappe TDeskbarMenu::AddNextItem()
160*323b6546SOliver Tappe {
161*323b6546SOliver Tappe 	if (fAddState == kStart)
162*323b6546SOliver Tappe 		return AddStandardDeskbarMenuItems();
163*323b6546SOliver Tappe 
164*323b6546SOliver Tappe 	TrackingHookData* data = fBarView->GetTrackingHookData();
165*323b6546SOliver Tappe 	if (fAddState == kAddingRecents) {
166*323b6546SOliver Tappe 		static const char* recentTitle[] = {
167*323b6546SOliver Tappe 			B_TRANSLATE_MARK("Recent documents"),
168*323b6546SOliver Tappe 			B_TRANSLATE_MARK("Recent folders"),
169*323b6546SOliver Tappe 			B_TRANSLATE_MARK("Recent applications")};
170*323b6546SOliver Tappe 		const int recentType[] = {kRecentDocuments, kRecentFolders,
171*323b6546SOliver Tappe 			kRecentApplications};
172*323b6546SOliver Tappe 		const int recentTypes = 3;
173*323b6546SOliver Tappe 		TRecentsMenu* recentItem[recentTypes];
174*323b6546SOliver Tappe 
175*323b6546SOliver Tappe 		bool enabled = false;
176*323b6546SOliver Tappe 
177*323b6546SOliver Tappe 		for (int i = 0; i < recentTypes; i++) {
178*323b6546SOliver Tappe 			recentItem[i]
179*323b6546SOliver Tappe 				= new TRecentsMenu(B_TRANSLATE_NOCOLLECT(recentTitle[i]),
180*323b6546SOliver Tappe 					fBarView, recentType[i]);
181*323b6546SOliver Tappe 
182*323b6546SOliver Tappe 			if (recentItem[i])
183*323b6546SOliver Tappe 				enabled |= recentItem[i]->RecentsEnabled();
184*323b6546SOliver Tappe 		}
185*323b6546SOliver Tappe 		if (enabled) {
186*323b6546SOliver Tappe 			AddSeparatorItem();
187*323b6546SOliver Tappe 
188*323b6546SOliver Tappe 			for (int i = 0; i < recentTypes; i++) {
189*323b6546SOliver Tappe 				if (!recentItem[i])
190*323b6546SOliver Tappe 					continue;
191*323b6546SOliver Tappe 
192*323b6546SOliver Tappe 				if (recentItem[i]->RecentsEnabled()) {
193*323b6546SOliver Tappe 					recentItem[i]->SetTypesList(TypesList());
194*323b6546SOliver Tappe 					recentItem[i]->SetTarget(Target());
195*323b6546SOliver Tappe 					AddItem(recentItem[i]);
196*323b6546SOliver Tappe 				}
197*323b6546SOliver Tappe 
198*323b6546SOliver Tappe 				if (data && fBarView && fBarView->Dragging()) {
199*323b6546SOliver Tappe 					recentItem[i]->InitTrackingHook(data->fTrackingHook,
200*323b6546SOliver Tappe 						&data->fTarget, data->fDragMessage);
201*323b6546SOliver Tappe 				}
202*323b6546SOliver Tappe 			}
203*323b6546SOliver Tappe 		}
204*323b6546SOliver Tappe 
205*323b6546SOliver Tappe 		AddSeparatorItem();
206*323b6546SOliver Tappe 		fAddState = kAddingDeskbarMenu;
207*323b6546SOliver Tappe 		return true;
208*323b6546SOliver Tappe 	}
209*323b6546SOliver Tappe 
210*323b6546SOliver Tappe 	if (fAddState == kAddingDeskbarMenu) {
211*323b6546SOliver Tappe 		// keep reentering and adding items
212*323b6546SOliver Tappe 		// until this returns false
213*323b6546SOliver Tappe 		bool done = BNavMenu::AddNextItem();
214*323b6546SOliver Tappe 		BMenuItem* item = ItemAt(CountItems() - 1);
215*323b6546SOliver Tappe 		if (item) {
216*323b6546SOliver Tappe 			BNavMenu* menu = dynamic_cast<BNavMenu*>(item->Menu());
217*323b6546SOliver Tappe 			if (menu) {
218*323b6546SOliver Tappe 				if (data && fBarView->Dragging()) {
219*323b6546SOliver Tappe 					menu->InitTrackingHook(data->fTrackingHook,
220*323b6546SOliver Tappe 						&data->fTarget, data->fDragMessage);
221*323b6546SOliver Tappe 				} else
222*323b6546SOliver Tappe 					menu->InitTrackingHook(0, NULL, NULL);
223*323b6546SOliver Tappe 			}
224*323b6546SOliver Tappe 		}
225*323b6546SOliver Tappe 
226*323b6546SOliver Tappe 		if (!done)
227*323b6546SOliver Tappe 			fAddState = kDone;
228*323b6546SOliver Tappe 		return done;
229*323b6546SOliver Tappe 	}
230*323b6546SOliver Tappe 
231*323b6546SOliver Tappe 	return false;
232*323b6546SOliver Tappe }
233*323b6546SOliver Tappe 
234*323b6546SOliver Tappe 
235*323b6546SOliver Tappe bool
236*323b6546SOliver Tappe TDeskbarMenu::AddStandardDeskbarMenuItems()
237*323b6546SOliver Tappe {
238*323b6546SOliver Tappe 	bool dragging = false;
239*323b6546SOliver Tappe 	if (fBarView)
240*323b6546SOliver Tappe 		dragging = fBarView->Dragging();
241*323b6546SOliver Tappe 
242*323b6546SOliver Tappe 	BMenuItem* item;
243*323b6546SOliver Tappe 	BRoster roster;
244*323b6546SOliver Tappe 	if (!roster.IsRunning(kTrackerSignature)) {
245*323b6546SOliver Tappe 		item = new BMenuItem(B_TRANSLATE("Restart Tracker"),
246*323b6546SOliver Tappe 			new BMessage(kRestartTracker));
247*323b6546SOliver Tappe 		AddItem(item);
248*323b6546SOliver Tappe 		AddSeparatorItem();
249*323b6546SOliver Tappe 	}
250*323b6546SOliver Tappe 
251*323b6546SOliver Tappe // One of them is used if HAIKU_DISTRO_COMPATIBILITY_OFFICIAL, and the other if
252*323b6546SOliver Tappe // not. However, we want both of them to end up in the catalog, so we have to
253*323b6546SOliver Tappe // make them visible to collectcatkeys in either case.
254*323b6546SOliver Tappe #if defined(B_COLLECTING_CATKEYS)||defined(HAIKU_DISTRO_COMPATIBILITY_OFFICIAL)
255*323b6546SOliver Tappe 	static const char* kAboutHaikuMenuItemStr = B_TRANSLATE_MARK(
256*323b6546SOliver Tappe 		"About Haiku");
257*323b6546SOliver Tappe #endif
258*323b6546SOliver Tappe 
259*323b6546SOliver Tappe #if defined(B_COLLECTING_CATKEYS)||!defined(HAIKU_DISTRO_COMPATIBILITY_OFFICIAL)
260*323b6546SOliver Tappe 	static const char* kAboutThisSystemMenuItemStr = B_TRANSLATE_MARK(
261*323b6546SOliver Tappe 		"About this system");
262*323b6546SOliver Tappe #endif
263*323b6546SOliver Tappe 
264*323b6546SOliver Tappe 	item = new BMenuItem(
265*323b6546SOliver Tappe #ifdef HAIKU_DISTRO_COMPATIBILITY_OFFICIAL
266*323b6546SOliver Tappe 	B_TRANSLATE_NOCOLLECT(kAboutHaikuMenuItemStr)
267*323b6546SOliver Tappe #else
268*323b6546SOliver Tappe 	B_TRANSLATE_NOCOLLECT(kAboutThisSystemMenuItemStr)
269*323b6546SOliver Tappe #endif
270*323b6546SOliver Tappe 		, new BMessage(kShowSplash));
271*323b6546SOliver Tappe 	item->SetEnabled(!dragging);
272*323b6546SOliver Tappe 	AddItem(item);
273*323b6546SOliver Tappe 
274*323b6546SOliver Tappe 	static const char* kFindMenuItemStr
275*323b6546SOliver Tappe 		= B_TRANSLATE_MARK("Find" B_UTF8_ELLIPSIS);
276*323b6546SOliver Tappe 
277*323b6546SOliver Tappe #ifdef SHOW_RECENT_FIND_ITEMS
278*323b6546SOliver Tappe 	item = new BMenuItem(
279*323b6546SOliver Tappe 		TrackerBuildRecentFindItemsMenu(kFindMenuItemStr),
280*323b6546SOliver Tappe 		new BMessage(kFindButton));
281*323b6546SOliver Tappe #else
282*323b6546SOliver Tappe 	item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kFindMenuItemStr),
283*323b6546SOliver Tappe 		new BMessage(kFindButton));
284*323b6546SOliver Tappe #endif
285*323b6546SOliver Tappe 	item->SetEnabled(!dragging);
286*323b6546SOliver Tappe 	AddItem(item);
287*323b6546SOliver Tappe 
288*323b6546SOliver Tappe 	item = new BMenuItem(B_TRANSLATE("Show replicants"),
289*323b6546SOliver Tappe 		new BMessage(kToggleDraggers));
290*323b6546SOliver Tappe 	item->SetEnabled(!dragging);
291*323b6546SOliver Tappe 	item->SetMarked(BDragger::AreDraggersDrawn());
292*323b6546SOliver Tappe 	AddItem(item);
293*323b6546SOliver Tappe 
294*323b6546SOliver Tappe 	static const char* kMountMenuStr = B_TRANSLATE_MARK("Mount");
295*323b6546SOliver Tappe 
296*323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR
297*323b6546SOliver Tappe 	DeskbarMountMenu* mountMenu = new DeskbarMountMenu(
298*323b6546SOliver Tappe 		B_TRANSLATE_NOCOLLECT(kMountMenuStr));
299*323b6546SOliver Tappe 	mountMenu->SetEnabled(!dragging);
300*323b6546SOliver Tappe 	AddItem(mountMenu);
301*323b6546SOliver Tappe #endif
302*323b6546SOliver Tappe 
303*323b6546SOliver Tappe 	item = new BMenuItem(B_TRANSLATE("Deskbar preferences" B_UTF8_ELLIPSIS),
304*323b6546SOliver Tappe 		new BMessage(kConfigShow));
305*323b6546SOliver Tappe 	item->SetTarget(be_app);
306*323b6546SOliver Tappe 	AddItem(item);
307*323b6546SOliver Tappe 
308*323b6546SOliver Tappe 	AddSeparatorItem();
309*323b6546SOliver Tappe 
310*323b6546SOliver Tappe 	BMenu* shutdownMenu = new BMenu(B_TRANSLATE("Shutdown" B_UTF8_ELLIPSIS));
311*323b6546SOliver Tappe 
312*323b6546SOliver Tappe 	item = new BMenuItem(B_TRANSLATE("Restart system"),
313*323b6546SOliver Tappe 		new BMessage(kRebootSystem));
314*323b6546SOliver Tappe 	item->SetEnabled(!dragging);
315*323b6546SOliver Tappe 	shutdownMenu->AddItem(item);
316*323b6546SOliver Tappe 
317*323b6546SOliver Tappe #if defined(APM_SUPPORT) || defined(B_COLLECTING_CATKEYS)
318*323b6546SOliver Tappe 	static const char* kSuspendMenuItemStr = B_TRANSLATE_MARK("Suspend");
319*323b6546SOliver Tappe #endif
320*323b6546SOliver Tappe 
321*323b6546SOliver Tappe #ifdef APM_SUPPORT
322*323b6546SOliver Tappe 	if (_kapm_control_(APM_CHECK_ENABLED) == B_OK) {
323*323b6546SOliver Tappe 		item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kSuspendMenuItemStr),
324*323b6546SOliver Tappe 			new BMessage(kSuspendSystem));
325*323b6546SOliver Tappe 		item->SetEnabled(!dragging);
326*323b6546SOliver Tappe 		shutdownMenu->AddItem(item);
327*323b6546SOliver Tappe 	}
328*323b6546SOliver Tappe #endif
329*323b6546SOliver Tappe 
330*323b6546SOliver Tappe 	item = new BMenuItem(B_TRANSLATE("Power off"),
331*323b6546SOliver Tappe 		new BMessage(kShutdownSystem));
332*323b6546SOliver Tappe 	item->SetEnabled(!dragging);
333*323b6546SOliver Tappe 	shutdownMenu->AddItem(item);
334*323b6546SOliver Tappe 	shutdownMenu->SetFont(be_plain_font);
335*323b6546SOliver Tappe 
336*323b6546SOliver Tappe 	shutdownMenu->SetTargetForItems(be_app);
337*323b6546SOliver Tappe 	BMessage* message = new BMessage(kShutdownSystem);
338*323b6546SOliver Tappe 	message->AddBool("confirm", true);
339*323b6546SOliver Tappe 	AddItem(new BMenuItem(shutdownMenu, message));
340*323b6546SOliver Tappe 
341*323b6546SOliver Tappe 	fAddState = kAddingRecents;
342*323b6546SOliver Tappe 
343*323b6546SOliver Tappe 	return true;
344*323b6546SOliver Tappe }
345*323b6546SOliver Tappe 
346*323b6546SOliver Tappe 
347*323b6546SOliver Tappe void
348*323b6546SOliver Tappe TDeskbarMenu::ClearMenuBuildingState()
349*323b6546SOliver Tappe {
350*323b6546SOliver Tappe 	fAddState = kDone;
351*323b6546SOliver Tappe 	fMenuBuilt = false;
352*323b6546SOliver Tappe 		// force the menu to get rebuilt each time
353*323b6546SOliver Tappe 	BNavMenu::ClearMenuBuildingState();
354*323b6546SOliver Tappe }
355*323b6546SOliver Tappe 
356*323b6546SOliver Tappe 
357*323b6546SOliver Tappe void
358*323b6546SOliver Tappe TDeskbarMenu::ResetTargets()
359*323b6546SOliver Tappe {
360*323b6546SOliver Tappe 	// This method does not recurse into submenus
361*323b6546SOliver Tappe 	// and does not affect menu items in submenus.
362*323b6546SOliver Tappe 	// (e.g. "Restart System" and "Power Off")
363*323b6546SOliver Tappe 
364*323b6546SOliver Tappe 	BNavMenu::ResetTargets();
365*323b6546SOliver Tappe 
366*323b6546SOliver Tappe 	// if we are dragging, set the target to whatever was set
367*323b6546SOliver Tappe 	// else set it to the default (Tracker)
368*323b6546SOliver Tappe 	if (!fBarView->Dragging())
369*323b6546SOliver Tappe 		SetTarget(DefaultTarget());
370*323b6546SOliver Tappe 
371*323b6546SOliver Tappe 	// now set the target for the menuitems to the currently
372*323b6546SOliver Tappe 	// set target, which may or may not be tracker
373*323b6546SOliver Tappe 	SetTargetForItems(Target());
374*323b6546SOliver Tappe 
375*323b6546SOliver Tappe 	for (int32 i = 0; ; i++) {
376*323b6546SOliver Tappe 		BMenuItem* item = ItemAt(i);
377*323b6546SOliver Tappe 		if (item == NULL)
378*323b6546SOliver Tappe 			break;
379*323b6546SOliver Tappe 
380*323b6546SOliver Tappe 		if (item->Message()) {
381*323b6546SOliver Tappe 			switch (item->Message()->what) {
382*323b6546SOliver Tappe 				case kFindButton:
383*323b6546SOliver Tappe 					item->SetTarget(BMessenger(kTrackerSignature));
384*323b6546SOliver Tappe 					break;
385*323b6546SOliver Tappe 
386*323b6546SOliver Tappe 				case kShowSplash:
387*323b6546SOliver Tappe 				case kToggleDraggers:
388*323b6546SOliver Tappe 				case kConfigShow:
389*323b6546SOliver Tappe 				case kAlwaysTop:
390*323b6546SOliver Tappe 				case kShowSeconds:
391*323b6546SOliver Tappe 				case kRebootSystem:
392*323b6546SOliver Tappe 				case kSuspendSystem:
393*323b6546SOliver Tappe 				case kShutdownSystem:
394*323b6546SOliver Tappe 					item->SetTarget(be_app);
395*323b6546SOliver Tappe 					break;
396*323b6546SOliver Tappe 			}
397*323b6546SOliver Tappe 		}
398*323b6546SOliver Tappe 	}
399*323b6546SOliver Tappe }
400*323b6546SOliver Tappe 
401*323b6546SOliver Tappe 
402*323b6546SOliver Tappe BPoint
403*323b6546SOliver Tappe TDeskbarMenu::ScreenLocation()
404*323b6546SOliver Tappe {
405*323b6546SOliver Tappe 	bool vertical = fBarView->Vertical();
406*323b6546SOliver Tappe 	int32 expando = (fBarView->State() == kExpandoState);
407*323b6546SOliver Tappe 	BPoint point;
408*323b6546SOliver Tappe 
409*323b6546SOliver Tappe 	BRect rect = Supermenu()->Bounds();
410*323b6546SOliver Tappe 	Supermenu()->ConvertToScreen(&rect);
411*323b6546SOliver Tappe 
412*323b6546SOliver Tappe 	if (expando && vertical && fBarView->Left()) {
413*323b6546SOliver Tappe 		PRINT(("Left\n"));
414*323b6546SOliver Tappe 		point = rect.RightTop() + BPoint(0, 3);
415*323b6546SOliver Tappe 	} else if (expando && vertical && !fBarView->Left()) {
416*323b6546SOliver Tappe 		PRINT(("Right\n"));
417*323b6546SOliver Tappe 		point = rect.LeftTop() - BPoint(Bounds().Width(), 0) + BPoint(0, 3);
418*323b6546SOliver Tappe 	} else
419*323b6546SOliver Tappe 		point = BMenu::ScreenLocation();
420*323b6546SOliver Tappe 
421*323b6546SOliver Tappe 	return point;
422*323b6546SOliver Tappe }
423*323b6546SOliver Tappe 
424*323b6546SOliver Tappe 
425*323b6546SOliver Tappe /*static*/
426*323b6546SOliver Tappe BMessenger
427*323b6546SOliver Tappe TDeskbarMenu::DefaultTarget()
428*323b6546SOliver Tappe {
429*323b6546SOliver Tappe 	// if Tracker is not available we target the BarApp
430*323b6546SOliver Tappe 	BMessenger target(kTrackerSignature);
431*323b6546SOliver Tappe 	if (target.IsValid())
432*323b6546SOliver Tappe 		return target;
433*323b6546SOliver Tappe 
434*323b6546SOliver Tappe 	return BMessenger(be_app);
435*323b6546SOliver Tappe }
436*323b6546SOliver Tappe 
437*323b6546SOliver Tappe 
438*323b6546SOliver Tappe //	#pragma mark -
439*323b6546SOliver Tappe 
440*323b6546SOliver Tappe 
441*323b6546SOliver Tappe TRecentsMenu::TRecentsMenu(const char* name, TBarView* bar, int32 which,
442*323b6546SOliver Tappe 		const char* signature, entry_ref* appRef)
443*323b6546SOliver Tappe 	: BNavMenu(name, B_REFS_RECEIVED, TDeskbarMenu::DefaultTarget()),
444*323b6546SOliver Tappe 	fWhich(which),
445*323b6546SOliver Tappe 	fAppRef(NULL),
446*323b6546SOliver Tappe 	fSignature(NULL),
447*323b6546SOliver Tappe 	fRecentsCount(0),
448*323b6546SOliver Tappe 	fRecentsEnabled(false),
449*323b6546SOliver Tappe 	fItemIndex(0),
450*323b6546SOliver Tappe 	fBarView(bar)
451*323b6546SOliver Tappe {
452*323b6546SOliver Tappe 	TBarApp* app = dynamic_cast<TBarApp*>(be_app);
453*323b6546SOliver Tappe 	if (app == NULL)
454*323b6546SOliver Tappe 		return;
455*323b6546SOliver Tappe 
456*323b6546SOliver Tappe 	switch (which) {
457*323b6546SOliver Tappe 		case kRecentDocuments:
458*323b6546SOliver Tappe 			fRecentsCount = app->Settings()->recentDocsCount;
459*323b6546SOliver Tappe 			fRecentsEnabled = app->Settings()->recentDocsEnabled;
460*323b6546SOliver Tappe 			break;
461*323b6546SOliver Tappe 		case kRecentApplications:
462*323b6546SOliver Tappe 			fRecentsCount = app->Settings()->recentAppsCount;
463*323b6546SOliver Tappe 			fRecentsEnabled = app->Settings()->recentAppsEnabled;
464*323b6546SOliver Tappe 			break;
465*323b6546SOliver Tappe 		case kRecentAppDocuments:
466*323b6546SOliver Tappe 			fRecentsCount = app->Settings()->recentDocsCount;
467*323b6546SOliver Tappe 			fRecentsEnabled = app->Settings()->recentDocsEnabled;
468*323b6546SOliver Tappe 			if (signature != NULL)
469*323b6546SOliver Tappe 				fSignature = strdup(signature);
470*323b6546SOliver Tappe 			if (appRef != NULL)
471*323b6546SOliver Tappe 				fAppRef = new entry_ref(*appRef);
472*323b6546SOliver Tappe 			break;
473*323b6546SOliver Tappe 		case kRecentFolders:
474*323b6546SOliver Tappe 			fRecentsCount = app->Settings()->recentFoldersCount;
475*323b6546SOliver Tappe 			fRecentsEnabled = app->Settings()->recentFoldersEnabled;
476*323b6546SOliver Tappe 			break;
477*323b6546SOliver Tappe 	}
478*323b6546SOliver Tappe }
479*323b6546SOliver Tappe 
480*323b6546SOliver Tappe 
481*323b6546SOliver Tappe TRecentsMenu::~TRecentsMenu()
482*323b6546SOliver Tappe {
483*323b6546SOliver Tappe 	delete fAppRef;
484*323b6546SOliver Tappe 	free(fSignature);
485*323b6546SOliver Tappe }
486*323b6546SOliver Tappe 
487*323b6546SOliver Tappe 
488*323b6546SOliver Tappe void
489*323b6546SOliver Tappe TRecentsMenu::DetachedFromWindow()
490*323b6546SOliver Tappe {
491*323b6546SOliver Tappe 	// BNavMenu::DetachedFromWindow sets the TypesList to NULL
492*323b6546SOliver Tappe 	BMenu::DetachedFromWindow();
493*323b6546SOliver Tappe }
494*323b6546SOliver Tappe 
495*323b6546SOliver Tappe 
496*323b6546SOliver Tappe bool
497*323b6546SOliver Tappe TRecentsMenu::StartBuildingItemList()
498*323b6546SOliver Tappe {
499*323b6546SOliver Tappe 	RemoveItems(0, CountItems(), true);
500*323b6546SOliver Tappe 
501*323b6546SOliver Tappe 	// !! note: don't call inherited from here
502*323b6546SOliver Tappe 	// the navref is not set for this menu
503*323b6546SOliver Tappe 	// but it still needs to be a draggable navmenu
504*323b6546SOliver Tappe 	// simply return true so that AddNextItem is called
505*323b6546SOliver Tappe 	//
506*323b6546SOliver Tappe 	// return BNavMenu::StartBuildingItemList();
507*323b6546SOliver Tappe 	return true;
508*323b6546SOliver Tappe }
509*323b6546SOliver Tappe 
510*323b6546SOliver Tappe 
511*323b6546SOliver Tappe bool
512*323b6546SOliver Tappe TRecentsMenu::AddNextItem()
513*323b6546SOliver Tappe {
514*323b6546SOliver Tappe 	if (fRecentsCount > 0 && fRecentsEnabled && AddRecents(fRecentsCount))
515*323b6546SOliver Tappe 		return true;
516*323b6546SOliver Tappe 
517*323b6546SOliver Tappe 	fItemIndex = 0;
518*323b6546SOliver Tappe 	return false;
519*323b6546SOliver Tappe }
520*323b6546SOliver Tappe 
521*323b6546SOliver Tappe 
522*323b6546SOliver Tappe bool
523*323b6546SOliver Tappe TRecentsMenu::AddRecents(int32 count)
524*323b6546SOliver Tappe {
525*323b6546SOliver Tappe 	if (fItemIndex == 0) {
526*323b6546SOliver Tappe 		fRecentList.MakeEmpty();
527*323b6546SOliver Tappe 		BRoster roster;
528*323b6546SOliver Tappe 
529*323b6546SOliver Tappe 		switch (fWhich) {
530*323b6546SOliver Tappe 			case kRecentDocuments:
531*323b6546SOliver Tappe 				roster.GetRecentDocuments(&fRecentList, count);
532*323b6546SOliver Tappe 				break;
533*323b6546SOliver Tappe 			case kRecentApplications:
534*323b6546SOliver Tappe 				roster.GetRecentApps(&fRecentList, count);
535*323b6546SOliver Tappe 				break;
536*323b6546SOliver Tappe 			case kRecentAppDocuments:
537*323b6546SOliver Tappe 				roster.GetRecentDocuments(&fRecentList, count, NULL,
538*323b6546SOliver Tappe 					fSignature);
539*323b6546SOliver Tappe 				break;
540*323b6546SOliver Tappe 			case kRecentFolders:
541*323b6546SOliver Tappe 				roster.GetRecentFolders(&fRecentList, count);
542*323b6546SOliver Tappe 				break;
543*323b6546SOliver Tappe 			default:
544*323b6546SOliver Tappe 				return false;
545*323b6546SOliver Tappe 		}
546*323b6546SOliver Tappe 	}
547*323b6546SOliver Tappe 
548*323b6546SOliver Tappe 	for (;;) {
549*323b6546SOliver Tappe 		entry_ref ref;
550*323b6546SOliver Tappe 		if (fRecentList.FindRef("refs", fItemIndex++, &ref) != B_OK)
551*323b6546SOliver Tappe 			break;
552*323b6546SOliver Tappe 
553*323b6546SOliver Tappe 		if (ref.name && strlen(ref.name) > 0) {
554*323b6546SOliver Tappe 			Model model(&ref, true);
555*323b6546SOliver Tappe 
556*323b6546SOliver Tappe 			if (fWhich != kRecentApplications) {
557*323b6546SOliver Tappe 				BMessage* message = new BMessage(B_REFS_RECEIVED);
558*323b6546SOliver Tappe 				if (fWhich == kRecentAppDocuments) {
559*323b6546SOliver Tappe 					// add application as handler
560*323b6546SOliver Tappe 					message->AddRef("handler", fAppRef);
561*323b6546SOliver Tappe 				}
562*323b6546SOliver Tappe 
563*323b6546SOliver Tappe 				ModelMenuItem* item = BNavMenu::NewModelItem(&model,
564*323b6546SOliver Tappe 					message, Target(), false, NULL, TypesList());
565*323b6546SOliver Tappe 
566*323b6546SOliver Tappe 				if (item)
567*323b6546SOliver Tappe 					AddItem(item);
568*323b6546SOliver Tappe 			} else {
569*323b6546SOliver Tappe 				// The application items expand to a list of recent documents
570*323b6546SOliver Tappe 				// for that application - so they must be handled extra
571*323b6546SOliver Tappe 				BFile file(&ref, B_READ_ONLY);
572*323b6546SOliver Tappe 				char signature[B_MIME_TYPE_LENGTH];
573*323b6546SOliver Tappe 
574*323b6546SOliver Tappe 				BAppFileInfo appInfo(&file);
575*323b6546SOliver Tappe 				if (appInfo.InitCheck() != B_OK
576*323b6546SOliver Tappe 					|| appInfo.GetSignature(signature) != B_OK)
577*323b6546SOliver Tappe 					continue;
578*323b6546SOliver Tappe 
579*323b6546SOliver Tappe 				ModelMenuItem* item = NULL;
580*323b6546SOliver Tappe 				BMessage doc;
581*323b6546SOliver Tappe 				be_roster->GetRecentDocuments(&doc, 1, NULL, signature);
582*323b6546SOliver Tappe 					// ToDo: check if the documents do exist at all to
583*323b6546SOliver Tappe 					//		avoid the creation of the submenu.
584*323b6546SOliver Tappe 
585*323b6546SOliver Tappe 				if (doc.CountNames(B_REF_TYPE) > 0) {
586*323b6546SOliver Tappe 					// create recents menu that will contain the recent docs of
587*323b6546SOliver Tappe 					// this app
588*323b6546SOliver Tappe 					TRecentsMenu* docs = new TRecentsMenu(model.Name(),
589*323b6546SOliver Tappe 						fBarView, kRecentAppDocuments, signature, &ref);
590*323b6546SOliver Tappe 					docs->SetTypesList(TypesList());
591*323b6546SOliver Tappe 					docs->SetTarget(Target());
592*323b6546SOliver Tappe 
593*323b6546SOliver Tappe 					item = new ModelMenuItem(&model, docs);
594*323b6546SOliver Tappe 				} else
595*323b6546SOliver Tappe 					item = new ModelMenuItem(&model, model.Name(), NULL);
596*323b6546SOliver Tappe 
597*323b6546SOliver Tappe 				if (item) {
598*323b6546SOliver Tappe 					// add refs-message so that the recent app can be launched
599*323b6546SOliver Tappe 					BMessage* msg = new BMessage(B_REFS_RECEIVED);
600*323b6546SOliver Tappe 					msg->AddRef("refs", &ref);
601*323b6546SOliver Tappe 					item->SetMessage(msg);
602*323b6546SOliver Tappe 					item->SetTarget(Target());
603*323b6546SOliver Tappe 
604*323b6546SOliver Tappe 					AddItem(item);
605*323b6546SOliver Tappe 				}
606*323b6546SOliver Tappe 			}
607*323b6546SOliver Tappe 
608*323b6546SOliver Tappe 			// return true so that we know to reenter this list
609*323b6546SOliver Tappe 			return true;
610*323b6546SOliver Tappe 		}
611*323b6546SOliver Tappe 	}
612*323b6546SOliver Tappe 
613*323b6546SOliver Tappe 	// return false if we are done with this list
614*323b6546SOliver Tappe 	return false;
615*323b6546SOliver Tappe }
616*323b6546SOliver Tappe 
617*323b6546SOliver Tappe 
618*323b6546SOliver Tappe void
619*323b6546SOliver Tappe TRecentsMenu::DoneBuildingItemList()
620*323b6546SOliver Tappe {
621*323b6546SOliver Tappe 	// !! note: don't call inherited here
622*323b6546SOliver Tappe 	// the object list is not built
623*323b6546SOliver Tappe 	// and this list does not need to be sorted
624*323b6546SOliver Tappe 	// BNavMenu::DoneBuildingItemList();
625*323b6546SOliver Tappe 
626*323b6546SOliver Tappe 	if (CountItems() > 0)
627*323b6546SOliver Tappe 		SetTargetForItems(Target());
628*323b6546SOliver Tappe }
629*323b6546SOliver Tappe 
630*323b6546SOliver Tappe 
631*323b6546SOliver Tappe void
632*323b6546SOliver Tappe TRecentsMenu::ClearMenuBuildingState()
633*323b6546SOliver Tappe {
634*323b6546SOliver Tappe 	fMenuBuilt = false;
635*323b6546SOliver Tappe 	BNavMenu::ClearMenuBuildingState();
636*323b6546SOliver Tappe }
637*323b6546SOliver Tappe 
638*323b6546SOliver Tappe 
639*323b6546SOliver Tappe void
640*323b6546SOliver Tappe TRecentsMenu::ResetTargets()
641*323b6546SOliver Tappe {
642*323b6546SOliver Tappe 	BNavMenu::ResetTargets();
643*323b6546SOliver Tappe 
644*323b6546SOliver Tappe 	// if we are dragging, set the target to whatever was set
645*323b6546SOliver Tappe 	// else set it to the default (Tracker)
646*323b6546SOliver Tappe 	if (!fBarView->Dragging())
647*323b6546SOliver Tappe 		SetTarget(TDeskbarMenu::DefaultTarget());
648*323b6546SOliver Tappe 
649*323b6546SOliver Tappe 	// now set the target for the menuitems to the currently
650*323b6546SOliver Tappe 	// set target, which may or may not be tracker
651*323b6546SOliver Tappe 	SetTargetForItems(Target());
652*323b6546SOliver Tappe }
653*323b6546SOliver Tappe 
654*323b6546SOliver Tappe 
655*323b6546SOliver Tappe //*****************************************************************************
656*323b6546SOliver Tappe //	#pragma mark -
657*323b6546SOliver Tappe 
658*323b6546SOliver Tappe 
659*323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR
660*323b6546SOliver Tappe 
661*323b6546SOliver Tappe DeskbarMountMenu::DeskbarMountMenu(const char* name)
662*323b6546SOliver Tappe 	: BPrivate::MountMenu(name)
663*323b6546SOliver Tappe {
664*323b6546SOliver Tappe 	SetFont(be_plain_font);
665*323b6546SOliver Tappe }
666*323b6546SOliver Tappe 
667*323b6546SOliver Tappe 
668*323b6546SOliver Tappe bool
669*323b6546SOliver Tappe DeskbarMountMenu::AddDynamicItem(add_state s)
670*323b6546SOliver Tappe {
671*323b6546SOliver Tappe 	BPrivate::MountMenu::AddDynamicItem(s);
672*323b6546SOliver Tappe 
673*323b6546SOliver Tappe 	SetTargetForItems(BMessenger(kTrackerSignature));
674*323b6546SOliver Tappe 
675*323b6546SOliver Tappe 	return false;
676*323b6546SOliver Tappe }
677*323b6546SOliver Tappe 
678*323b6546SOliver Tappe 
679*323b6546SOliver Tappe #endif
680*323b6546SOliver Tappe 
681