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