xref: /haiku/src/apps/deskbar/BarView.cpp (revision 70d5966963513ff47a456ba70b7d2eec0f99648d)
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 trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
32 All rights reserved.
33 */
34 
35 #include <Debug.h>
36 
37 #include "BarView.h"
38 
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 
43 #include <AppFileInfo.h>
44 #include <Bitmap.h>
45 #include <Directory.h>
46 #include <NodeInfo.h>
47 #include <Roster.h>
48 #include <Screen.h>
49 #include <String.h>
50 
51 #include "icons.h"
52 #include "BarApp.h"
53 #include "BarMenuBar.h"
54 #include "BarWindow.h"
55 #include "BeMenu.h"
56 #include "DeskBarUtils.h"
57 #include "ExpandoMenuBar.h"
58 #include "FSUtils.h"
59 #include "ResourceSet.h"
60 #include "StatusView.h"
61 #include "TeamMenuItem.h"
62 
63 
64 const int32 kDefaultRecentDocCount = 10;
65 const int32 kDefaultRecentFolderCount = 10;
66 const int32 kDefaultRecentAppCount = 10;
67 
68 const int32 kMenuTrackMargin = 20;
69 
70 TBarView::TBarView(BRect frame, bool vertical, bool left, bool top,
71 		bool showInterval, uint32 state, float, bool showTime)
72 	: BView(frame, "BarView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW),
73 	fBarMenuBar(NULL),
74 	fExpando(NULL),
75 	fTrayLocation(1),
76 	fShowInterval(showInterval),
77 	fShowClock(showTime),
78 	fVertical(vertical),
79 	fTop(top),
80 	fLeft(left),
81 	fState(static_cast<int32>(state)),
82 	fRefsRcvdOnly(true),
83 	fDragMessage(NULL),
84 	fCachedTypesList(NULL),
85 	fMaxRecentDocs(kDefaultRecentDocCount),
86 	fMaxRecentApps(kDefaultRecentAppCount),
87 	fLastDragItem(NULL)
88 {
89 	fReplicantTray = new TReplicantTray(this, fVertical);
90 	fDragRegion = new TDragRegion(this, fReplicantTray);
91 	fDragRegion->AddChild(fReplicantTray);
92 	if (fTrayLocation != 0)
93 		AddChild(fDragRegion);
94 }
95 
96 
97 TBarView::~TBarView()
98 {
99 	delete fDragMessage;
100 	delete fCachedTypesList;
101 }
102 
103 
104 void
105 TBarView::AttachedToWindow()
106 {
107 	BView::AttachedToWindow();
108 
109 	SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR));
110 	SetFont(be_plain_font);
111 
112 	UpdateAutoRaise();
113 	UpdatePlacement();
114 
115 	fTrackingHookData.fTrackingHook = MenuTrackingHook;
116 	fTrackingHookData.fTarget = BMessenger(this);
117 	fTrackingHookData.fDragMessage = new BMessage(B_REFS_RECEIVED);
118 }
119 
120 
121 void
122 TBarView::DetachedFromWindow()
123 {
124 	delete fTrackingHookData.fDragMessage;
125 	fTrackingHookData.fDragMessage = NULL;
126 }
127 
128 
129 void
130 TBarView::Draw(BRect)
131 {
132 	BRect bounds(Bounds());
133 
134 	rgb_color hilite = tint_color(ViewColor(), B_DARKEN_1_TINT);
135 	rgb_color light = tint_color(ViewColor(), B_LIGHTEN_2_TINT);
136 
137 	SetHighColor(hilite);
138 	if (AcrossTop())
139 		StrokeLine(bounds.LeftBottom(), bounds.RightBottom());
140 	else if (AcrossBottom())
141 		StrokeLine(bounds.LeftTop(), bounds.RightTop());
142 
143 	if (Vertical() && Expando()) {
144 		SetHighColor(hilite);
145 		BRect frame(fExpando->Frame());
146 		StrokeLine(BPoint(frame.left, frame.top - 1),
147 			BPoint(frame.right, frame.top -1));
148 	}
149 }
150 
151 
152 void
153 TBarView::MessageReceived(BMessage* message)
154 {
155 	switch (message->what) {
156 		case B_REFS_RECEIVED:
157 			// received when an item is selected during DnD
158 			// message is targeted here from Be menu
159 			HandleBeMenu(message);
160 			break;
161 
162 		case B_ARCHIVED_OBJECT:
163 		{
164 			// this message has been retargeted to here
165 			// instead of directly to the replicant tray
166 			// so that I can follow the common pathway
167 			// for adding icons to the tray
168 			int32 id;
169 			AddItem(new BMessage(*message), B_DESKBAR_TRAY, &id);
170 			break;
171 		}
172 
173 		default:
174 			BView::MessageReceived(message);
175 	}
176 }
177 
178 
179 void
180 TBarView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
181 {
182 	if (Window() == NULL || EventMask() == 0)
183 		return;
184 
185 	// Auto-Raise
186 
187 	where = ConvertToScreen(where);
188 	BScreen screen(Window());
189 	BRect frame = screen.Frame();
190 	if (where.x == frame.left || where.x == frame.right
191 		|| where.y == frame.top || where.y == frame.bottom) {
192 		// cursor is on screen edge
193 		if (Window()->Frame().Contains(where))
194 			Window()->Activate();
195 	}
196 }
197 
198 
199 void
200 TBarView::PlaceBeMenu()
201 {
202 	// top or bottom, full
203 	if (!fVertical && fBarMenuBar) {
204 		fBarMenuBar->RemoveSelf();
205 		delete fBarMenuBar;
206 		fBarMenuBar = NULL;
207 	}
208 
209 	//	top or bottom expando mode has Be menu built in for tracking
210 	//	only for vertical mini or expanded
211 	//	mini mode will have team menu added as part of BarMenuBar
212 	if (fVertical && !fBarMenuBar) {
213 		//	create the Be menu
214 		BRect mbarFrame(Bounds());
215 		mbarFrame.bottom = mbarFrame.top + kMenuBarHeight;
216 		fBarMenuBar = new TBarMenuBar(this, mbarFrame, "BarMenuBar");
217 		AddChild(fBarMenuBar);
218 	}
219 
220 	//	if there isn't a bemenu at this point,
221 	//	DB should be in top/bottom mode, else error
222 	if (!fBarMenuBar)
223 		return;
224 
225 	float width = sMinimumWindowWidth;
226 	BPoint loc(B_ORIGIN);
227 	BRect menuFrame(fBarMenuBar->Frame());
228 	if (fState == kFullState) {
229 		fBarMenuBar->RemoveTeamMenu();
230 		width = 8 + 16 + 8;
231 		loc = Bounds().LeftTop();
232 	} else if (fState == kExpandoState) {
233 		// shows apps below tray
234 		fBarMenuBar->RemoveTeamMenu();
235 		if (fVertical)
236 			width += 1;
237 		else
238 			width = floorf(width) / 2;
239 		loc = Bounds().LeftTop();
240 	} else
241 		// mini mode, BeMenu next to team menu
242 		fBarMenuBar->AddTeamMenu();
243 
244 	fBarMenuBar->SmartResize(width, menuFrame.Height());
245 	fBarMenuBar->MoveTo(loc);
246 }
247 
248 
249 void
250 TBarView::PlaceTray(bool, bool, BRect screenFrame)
251 {
252 	BPoint statusLoc;
253 	if (fState == kFullState) {
254 		fDragRegion->ResizeTo(fBarMenuBar->Frame().Width(), kMenuBarHeight);
255 		statusLoc.y = fBarMenuBar->Frame().bottom + 1;
256 		statusLoc.x = 0;
257 		fDragRegion->MoveTo(statusLoc);
258 
259 		if (!fReplicantTray->IsHidden())
260 			fReplicantTray->Hide();
261 
262 		return;
263 	}
264 
265 	if (fReplicantTray->IsHidden())
266 		fReplicantTray->Show();
267 
268 	if (fTrayLocation != 0) {
269 		fReplicantTray->SetMultiRow(fVertical);
270 		fReplicantTray->RealignReplicants();
271 		fDragRegion->ResizeToPreferred();
272 
273 		if (fVertical) {
274 			statusLoc.y = fBarMenuBar->Frame().bottom + 1;
275 			statusLoc.x = 0;
276 			if (Left() && Vertical())
277 				fReplicantTray->MoveTo(5, 2);
278 			else
279 				fReplicantTray->MoveTo(2, 2);
280 		} else {
281 			statusLoc.x = screenFrame.right - fDragRegion->Bounds().Width();
282 			statusLoc.y = -1;
283 		}
284 
285 		fDragRegion->MoveTo(statusLoc);
286 	}
287 }
288 
289 
290 void
291 TBarView::PlaceApplicationBar(BRect screenFrame)
292 {
293 	if (fExpando != NULL) {
294 		fExpando->RemoveSelf();
295 		delete fExpando;
296 		fExpando = NULL;
297 	}
298 	if (fState == kMiniState)
299 		return;
300 
301 	BRect expandoFrame(0, 0, 0, 0);
302 	if (fVertical) {
303 		// top left/right
304 		if (fTrayLocation != 0)
305 			expandoFrame.top = fDragRegion->Frame().bottom + 1;
306 		else
307 			expandoFrame.top = fBarMenuBar->Frame().bottom + 1;
308 
309 		expandoFrame.bottom = expandoFrame.top + 1;
310 		if (fState == kFullState)
311 			expandoFrame.right = fBarMenuBar->Frame().Width();
312 		else
313 			expandoFrame.right = sMinimumWindowWidth;
314 	} else {
315 		// top or bottom
316 		expandoFrame.top = 0;
317 		expandoFrame.bottom = kHModeHeight;
318 		if (fTrayLocation != 0)
319 			expandoFrame.right = fDragRegion->Frame().left - 1;
320 		else
321 			expandoFrame.right = screenFrame.Width();
322 	}
323 
324 	fExpando = new TExpandoMenuBar(this, expandoFrame, "ExpandoMenuBar",
325 		fVertical, fState != kFullState);
326 	AddChild(fExpando);
327 }
328 
329 
330 void
331 TBarView::GetPreferredWindowSize(BRect screenFrame, float* width, float* height)
332 {
333 	float windowHeight = 0;
334 	float windowWidth = sMinimumWindowWidth;
335 	if (fState == kFullState) {
336 		windowHeight = screenFrame.bottom;
337 		windowWidth = fBarMenuBar->Frame().Width();
338 	} else if (fState == kExpandoState) {
339 		if (fVertical) {
340 			// top left or right
341 			windowHeight = fExpando->Frame().bottom;
342 		} else {
343 			// top or bottom, full
344 			fExpando->CheckItemSizes(0);
345 			windowHeight = kHModeHeight;
346 			windowWidth = screenFrame.Width();
347 		}
348 	} else {
349 		// four corners
350 		if (fTrayLocation != 0)
351 			windowHeight = fDragRegion->Frame().bottom;
352 		else
353 			windowHeight = fBarMenuBar->Frame().bottom;
354 	}
355 
356 	*width = windowWidth;
357 	*height = windowHeight;
358 }
359 
360 
361 void
362 TBarView::SizeWindow(BRect screenFrame)
363 {
364 	float windowWidth, windowHeight;
365 	GetPreferredWindowSize(screenFrame, &windowWidth, &windowHeight);
366 	Window()->ResizeTo(windowWidth, windowHeight);
367 	if (fExpando)
368 		fExpando->CheckForSizeOverrun();
369 }
370 
371 
372 void
373 TBarView::PositionWindow(BRect screenFrame)
374 {
375 	float windowWidth, windowHeight;
376 	GetPreferredWindowSize(screenFrame, &windowWidth, &windowHeight);
377 
378 	BPoint moveLoc(0, 0);
379 	// right, expanded
380 	if (!fLeft && fVertical) {
381 		if (fState == kFullState)
382 			moveLoc.x = screenFrame.right - fBarMenuBar->Frame().Width();
383 		else
384 			moveLoc.x = screenFrame.right - windowWidth;
385 	}
386 
387 	// bottom, full or corners
388 	if (!fTop)
389 		moveLoc.y = screenFrame.bottom - windowHeight;
390 
391 	Window()->MoveTo(moveLoc);
392 }
393 
394 
395 void
396 TBarView::SaveSettings()
397 {
398 	desk_settings* settings = ((TBarApp*)be_app)->Settings();
399 
400 	settings->vertical = Vertical();
401 	settings->left = Left();
402 	settings->top = Top();
403 	settings->ampmMode = MilTime();
404 	settings->state = (uint32)State();
405 	settings->width = 0;
406 	settings->showTime = ShowingClock();
407 
408 	fReplicantTray->RememberClockSettings();
409 	settings->alwaysOnTop = (Window()->Feel() & B_FLOATING_ALL_WINDOW_FEEL)
410 		!= 0;
411 }
412 
413 
414 void
415 TBarView::UpdateAutoRaise()
416 {
417 	if (((TBarApp*)be_app)->Settings()->autoRaise)
418 		SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
419 	else
420 		SetEventMask(0);
421 }
422 
423 
424 void
425 TBarView::UpdatePlacement()
426 {
427 	ChangeState(fState, fVertical, fLeft, fTop);
428 }
429 
430 
431 void
432 TBarView::ChangeState(int32 state, bool vertical, bool left, bool top)
433 {
434 	bool vertSwap = (fVertical != vertical);
435 	bool leftSwap = (fLeft != left);
436 	bool stateChanged = (fState != state);
437 
438 	fState = state;
439 	fVertical = vertical;
440 	fLeft = left;
441 	fTop = top;
442 
443 	// Send a message to the preferences window to let it know to enable
444 	// or disabled preference items
445 	if (stateChanged || vertSwap)
446 		be_app->PostMessage(kStateChanged);
447 
448 	BRect screenFrame = (BScreen(Window())).Frame();
449 
450 	PlaceBeMenu();
451 	PlaceTray(vertSwap, leftSwap, screenFrame);
452 
453 	// We need to keep track of what apps are expanded.
454 	BList expandedItems;
455 	BString* signature = NULL;
456 	if (fVertical && Expando()
457 		&& static_cast<TBarApp*>(be_app)->Settings()->superExpando) {
458 		// Get a list of the signatures of expanded apps. Can't use
459 		// team_id because there can be more than one team per application
460 		if (fVertical && Expando() && vertical && fExpando) {
461 			for (int index = 0; index < fExpando->CountItems(); index++) {
462 				TTeamMenuItem* item
463 					= dynamic_cast<TTeamMenuItem*>(fExpando->ItemAt(index));
464 				if (item != NULL && item->IsExpanded()) {
465 					signature = new BString(item->Signature());
466 					expandedItems.AddItem((void*)signature);
467 				}
468 			}
469 		}
470 	}
471 
472  	PlaceApplicationBar(screenFrame);
473  	SizeWindow(screenFrame);
474  	PositionWindow(screenFrame);
475  	Window()->UpdateIfNeeded();
476 
477 	// Re-expand those apps.
478 	if (expandedItems.CountItems() > 0) {
479 		for (int sigIndex = expandedItems.CountItems(); sigIndex-- > 0;) {
480 			signature = static_cast<BString*>(expandedItems.ItemAt(sigIndex));
481 			if (signature == NULL)
482 				continue;
483 
484 			// Start at the 'bottom' of the list working up.
485 			// Prevents being thrown off by expanding items.
486 			for (int teamIndex = fExpando->CountItems(); teamIndex-- > 0;) {
487 				TTeamMenuItem* item
488 					= dynamic_cast<TTeamMenuItem*>(fExpando->ItemAt(teamIndex));
489 				if (item != NULL && !signature->Compare(item->Signature())) {
490 					item->ToggleExpandState(false);
491 					break;
492 				}
493 			}
494 		}
495 
496 		// Clean up expanded signature list.
497 		while (!expandedItems.IsEmpty()) {
498 			delete static_cast<BString*>(expandedItems.RemoveItem((int32)0));
499 		}
500 
501 		fExpando->SizeWindow();
502 	}
503 
504 	Invalidate();
505 }
506 
507 
508 //	window placement functions
509 
510 bool
511 TBarView::Vertical() const
512 {
513 	return fVertical;
514 }
515 
516 
517 bool
518 TBarView::Left() const
519 {
520 	return fLeft;
521 }
522 
523 
524 bool
525 TBarView::AcrossTop() const
526 {
527 	return fTop && !fVertical;
528 }
529 
530 
531 bool
532 TBarView::AcrossBottom() const
533 {
534 	return !fTop && !fVertical;
535 }
536 
537 
538 bool
539 TBarView::Expando() const
540 {
541 	return fState == kExpandoState;
542 }
543 
544 
545 bool
546 TBarView::Top() const
547 {
548 	return fTop;
549 }
550 
551 
552 int32
553 TBarView::State() const
554 {
555 	return fState;
556 }
557 
558 
559 // optional functionality functions
560 
561 bool
562 TBarView::MilTime() const
563 {
564 	return fShowInterval;
565 }
566 
567 
568 void
569 TBarView::ShowClock(bool on)
570 {
571 	fShowClock = on;
572 }
573 
574 
575 bool
576 TBarView::ShowingClock() const
577 {
578 	return fShowClock;
579 }
580 
581 
582 //	#pragma mark - Drag and Drop
583 
584 
585 void
586 TBarView::CacheDragData(const BMessage* incoming)
587 {
588 	if (!incoming)
589 		return;
590 
591 	if (Dragging() && SpringLoadedFolderCompareMessages(incoming, fDragMessage))
592 		return;
593 
594 	// disposes then fills cached drag message and
595 	// mimetypes list
596 	SpringLoadedFolderCacheDragData(incoming, &fDragMessage, &fCachedTypesList);
597 }
598 
599 
600 static void
601 init_tracking_hook(BMenuItem* item,
602 	bool (*hookFunction)(BMenu*, void*), void* state)
603 {
604 	if (!item)
605 		return;
606 
607 	BMenu* windowMenu = item->Submenu();
608 	if (windowMenu) {
609 		// have a menu, set the tracking hook
610 		windowMenu->SetTrackingHook(hookFunction, state);
611 	}
612 }
613 
614 
615 status_t
616 TBarView::DragStart()
617 {
618 	if (!Dragging())
619 		return B_OK;
620 
621 	BPoint loc;
622 	uint32 buttons;
623 	GetMouse(&loc, &buttons);
624 
625 	if (fExpando && fExpando->Frame().Contains(loc)) {
626 		ConvertToScreen(&loc);
627 		BPoint expandoLocation = fExpando->ConvertFromScreen(loc);
628 		TTeamMenuItem* item = fExpando->TeamItemAtPoint(expandoLocation);
629 
630 		if (fLastDragItem)
631 			init_tracking_hook(fLastDragItem, NULL, NULL);
632 
633 		if (item) {
634 			if (item == fLastDragItem)
635 				return B_OK;
636 
637 			fLastDragItem = item;
638 		}
639 	}
640 
641 	return B_OK;
642 }
643 
644 
645 bool
646 TBarView::MenuTrackingHook(BMenu* menu, void* castToThis)
647 {
648 	// return true if the menu should go away
649 	TrackingHookData* data = static_cast<TrackingHookData*>(castToThis);
650 	if (!data)
651 		return false;
652 
653 	TBarView* barview = dynamic_cast<TBarView*>(data->fTarget.Target(NULL));
654 	if (!barview || !menu->LockLooper())
655 		return false;
656 
657 	uint32 buttons;
658 	BPoint location;
659 	menu->GetMouse(&location, &buttons);
660 
661 	bool endMenu = true;
662 	BRect frame(menu->Bounds());
663 	frame.InsetBy(-kMenuTrackMargin, -kMenuTrackMargin);
664 
665 	if (frame.Contains(location)) {
666 		// if current loc is still in the menu
667 		// keep tracking
668 		endMenu = false;
669 	} else {
670 		// see if the mouse is in the team/be menu item
671 		menu->ConvertToScreen(&location);
672 		if (barview->LockLooper()) {
673 			TExpandoMenuBar* expando = barview->ExpandoMenuBar();
674 			TBeMenu* bemenu
675 				= (dynamic_cast<TBarWindow*>(barview->Window()))->BeMenu();
676 
677 			if (bemenu && bemenu->LockLooper()) {
678 				bemenu->ConvertFromScreen(&location);
679 				if (bemenu->Frame().Contains(location))
680 					endMenu = false;
681 
682 				bemenu->UnlockLooper();
683 			}
684 
685 			if (endMenu && expando) {
686 				expando->ConvertFromScreen(&location);
687 				BMenuItem* item = expando->TeamItemAtPoint(location);
688 				if (item)
689 					endMenu = false;
690 			}
691 			barview->UnlockLooper();
692 		}
693 	}
694 
695 	menu->UnlockLooper();
696 	return endMenu;
697 }
698 
699 
700 // used by WindowMenu and TeamMenu to
701 // set the tracking hook for dragging
702 TrackingHookData*
703 TBarView::GetTrackingHookData()
704 {
705 	// all tracking hook data is
706 	// preset in AttachedToWindow
707 	// data should never change
708 	return &fTrackingHookData;
709 }
710 
711 
712 void
713 TBarView::DragStop(bool full)
714 {
715 	if (!Dragging())
716 		return;
717 
718 	if (fExpando) {
719 		if (fLastDragItem) {
720 			init_tracking_hook(fLastDragItem, NULL, NULL);
721 			fLastDragItem = NULL;
722 		}
723 	}
724 
725 	if (full) {
726 		delete fDragMessage;
727 		fDragMessage = NULL;
728 
729 		delete fCachedTypesList;
730 		fCachedTypesList = NULL;
731 	}
732 }
733 
734 
735 bool
736 TBarView::AppCanHandleTypes(const char* signature)
737 {
738 	// used for filtering apps/teams in the ExpandoMenuBar and TeamMenu
739 
740 	if (modifiers() & B_CONTROL_KEY) {
741 		// control key forces acceptance, just like drag&drop on icons
742 		return true;
743 	}
744 
745 	if (!signature || strlen(signature) == 0
746 		|| !fCachedTypesList || fCachedTypesList->CountItems() == 0)
747 		return false;
748 
749 	if (strcmp(signature, kTrackerSignature) == 0) {
750 		// tracker should support all types
751 		// and should pass them on to the appropriate application
752 		return true;
753 	}
754 
755 	entry_ref hintref;
756 	BMimeType appmime(signature);
757 	if (appmime.GetAppHint(&hintref) != B_OK)
758 		return false;
759 
760 	// an app was found, now see if it supports any of
761 	// the refs in the message
762 	BFile file(&hintref, O_RDONLY);
763 	BAppFileInfo fileinfo(&file);
764 
765 	// scan the cached mimetype list and see if this app
766 	// supports anything in the list
767 	// only one item needs to match in the list of refs
768 
769 	int32 count = fCachedTypesList->CountItems();
770 	for (int32 i = 0 ; i < count ; i++) {
771 		if (fileinfo.IsSupportedType(fCachedTypesList->ItemAt(i)->String()))
772 			return true;
773 	}
774 
775 	return false;
776 }
777 
778 
779 void
780 TBarView::SetDragOverride(bool on)
781 {
782 	fRefsRcvdOnly = on;
783 }
784 
785 
786 bool
787 TBarView::DragOverride()
788 {
789 	return fRefsRcvdOnly;
790 }
791 
792 
793 status_t
794 TBarView::SendDragMessage(const char* signature, entry_ref* ref)
795 {
796 	status_t err = B_ERROR;
797 	if (fDragMessage) {
798 		if (fRefsRcvdOnly) {
799 			// current message sent to apps is only B_REFS_RECEIVED
800 			fDragMessage->what = B_REFS_RECEIVED;
801 		}
802 
803 		BRoster roster;
804 		if (signature && strlen(signature) > 0 && roster.IsRunning(signature)) {
805 			BMessenger mess(signature);
806 			// drag message is still owned by DB, copy is sent
807 			// can toss it after send
808 			err = mess.SendMessage(fDragMessage);
809 		} else if (ref) {
810 			FSLaunchItem((const entry_ref*)ref, (const BMessage*)fDragMessage,
811 				true, true);
812 		} else if (signature && strlen(signature) > 0) {
813 			roster.Launch(signature, fDragMessage);
814 		}
815 	}
816 	return err;
817 }
818 
819 
820 bool
821 TBarView::InvokeItem(const char* signature)
822 {
823 	// sent from TeamMenuItem
824 	if (Dragging() && AppCanHandleTypes(signature)) {
825 		SendDragMessage(signature);
826 		// invoking okay to toss memory
827 		DragStop(true);
828 		return true;
829 	}
830 
831 	return false;
832 }
833 
834 
835 void
836 TBarView::HandleBeMenu(BMessage* messagewithdestination)
837 {
838 	if (!Dragging())
839 		return;
840 
841 	// in mini-mode
842 	if (Vertical() && !Expando()) {
843 		// if drop is in the team menu, bail
844 		if (fBarMenuBar->CountItems() >= 2) {
845 			uint32 buttons;
846 			BPoint location;
847 			GetMouse(&location, &buttons);
848 			if (fBarMenuBar->ItemAt(1)->Frame().Contains(location))
849 				return;
850 		}
851 	}
852 
853 	if (messagewithdestination) {
854 		entry_ref ref;
855 		if (messagewithdestination->FindRef("refs", &ref) == B_OK) {
856 			BEntry entry(&ref, true);
857 			if (entry.IsDirectory()) {
858 				// if the ref received (should only be 1) is a directory
859 				// then add the drag refs to the directory
860 				AddRefsToBeMenu(DragMessage(), &ref);
861 			} else
862 				SendDragMessage(NULL, &ref);
863 		}
864 	} else {
865 		// adds drag refs to top level in be menu
866 		AddRefsToBeMenu(DragMessage(), NULL);
867 	}
868 
869 	// clean up drag message and types list
870 	DragStop(true);
871 }
872 
873 
874 //	#pragma mark - Add-ons
875 
876 
877 // shelf is ignored for now,
878 // it exists in anticipation of having other 'shelves' for
879 // storing items
880 
881 status_t
882 TBarView::ItemInfo(int32 id, const char** name, DeskbarShelf* shelf)
883 {
884 	*shelf = B_DESKBAR_TRAY;
885 	return fReplicantTray->ItemInfo(id, name);
886 }
887 
888 
889 status_t
890 TBarView::ItemInfo(const char* name, int32* id, DeskbarShelf* shelf)
891 {
892 	*shelf = B_DESKBAR_TRAY;
893 	return fReplicantTray->ItemInfo(name, id);
894 }
895 
896 
897 bool
898 TBarView::ItemExists(int32 id, DeskbarShelf)
899 {
900 	return fReplicantTray->IconExists(id);
901 }
902 
903 
904 bool
905 TBarView::ItemExists(const char* name, DeskbarShelf)
906 {
907 	return fReplicantTray->IconExists(name);
908 }
909 
910 
911 int32
912 TBarView::CountItems(DeskbarShelf)
913 {
914 	return fReplicantTray->IconCount();
915 }
916 
917 
918 status_t
919 TBarView::AddItem(BMessage* item, DeskbarShelf, int32* id)
920 {
921 	return fReplicantTray->AddIcon(item, id);
922 }
923 
924 
925 void
926 TBarView::RemoveItem(int32 id)
927 {
928 	fReplicantTray->RemoveIcon(id);
929 }
930 
931 
932 void
933 TBarView::RemoveItem(const char* name, DeskbarShelf)
934 {
935 	fReplicantTray->RemoveIcon(name);
936 }
937 
938 
939 BRect
940 TBarView::OffsetIconFrame(BRect rect) const
941 {
942 	BRect frame(Frame());
943 	frame.left += fDragRegion->Frame().left + fReplicantTray->Frame().left
944 		+ rect.left;
945 	frame.top += fDragRegion->Frame().top + fReplicantTray->Frame().top
946 		+ rect.top;
947 
948 	frame.right = frame.left + rect.Width();
949 	frame.bottom = frame.top + rect.Height();
950 
951 	return frame;
952 }
953 
954 
955 BRect
956 TBarView::IconFrame(int32 id) const
957 {
958 	return OffsetIconFrame(fReplicantTray->IconFrame(id));
959 }
960 
961 
962 BRect
963 TBarView::IconFrame(const char* name) const
964 {
965 	return OffsetIconFrame(fReplicantTray->IconFrame(name));
966 }
967 
968