6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
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:
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.
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.
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.
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.
36 #include "RecentItems.h"
40 #include "Attributes.h"
41 #include "IconMenuItem.h"
47 #include "Utilities.h"
50 class RecentItemsMenu
: public BSlowMenu
{
52 RecentItemsMenu(const char* title
, BMessage
* openMessage
,
53 BHandler
* itemTarget
, int32 maxItems
);
54 virtual ~RecentItemsMenu();
56 virtual bool StartBuildingItemList();
57 virtual bool AddNextItem();
58 virtual void DoneBuildingItemList() {}
59 virtual void ClearMenuBuildingState();
62 virtual const BMessage
* FileMessage()
67 virtual const BMessage
* ContainerMessage()
72 BRecentItemsList
* fIterator
;
73 BMessage
* fTargetMesage
;
74 BHandler
* fItemTarget
;
81 class RecentFilesMenu
: public RecentItemsMenu
{
83 RecentFilesMenu(const char* title
, BMessage
* openFileMessage
,
84 BMessage
* openFolderMessage
, BHandler
* target
,
85 int32 maxItems
, bool navMenuFolders
, const char* ofType
,
86 const char* openedByAppSig
);
88 RecentFilesMenu(const char* title
, BMessage
* openFileMessage
,
89 BMessage
* openFolderMessage
, BHandler
* target
,
90 int32 maxItems
, bool navMenuFolders
, const char* ofTypeList
[],
91 int32 ofTypeListCount
, const char* openedByAppSig
);
93 virtual ~RecentFilesMenu();
96 virtual const BMessage
* ContainerMessage()
97 { return openFolderMessage
; }
100 BMessage
* openFolderMessage
;
104 class RecentFoldersMenu
: public RecentItemsMenu
{
106 RecentFoldersMenu(const char* title
, BMessage
* openMessage
,
107 BHandler
* target
, int32 maxItems
, bool navMenuFolders
,
108 const char* openedByAppSig
);
112 class RecentAppsMenu
: public RecentItemsMenu
{
114 RecentAppsMenu(const char* title
, BMessage
* openMessage
,
115 BHandler
* target
, int32 maxItems
);
119 // #pragma mark - RecentItemsMenu
122 RecentItemsMenu::RecentItemsMenu(const char* title
, BMessage
* openMessage
,
123 BHandler
* itemTarget
, int32 maxItems
)
127 fTargetMesage(openMessage
),
128 fItemTarget(itemTarget
),
136 RecentItemsMenu::~RecentItemsMenu()
139 delete fTargetMesage
;
144 RecentItemsMenu::AddNextItem()
146 BMenuItem
* item
= fIterator
->GetNextMenuItem(FileMessage(),
147 ContainerMessage(), fItemTarget
);
154 return fCount
< fMaxCount
- 1 && (fSanityCount
< fMaxCount
+ 20);
155 // fSanityCount is a hacky way of dealing with a lot of stale
161 RecentItemsMenu::StartBuildingItemList()
163 // remove any preexisting items
164 int32 itemCount
= CountItems();
166 delete RemoveItem((int32
)0);
177 RecentItemsMenu::ClearMenuBuildingState()
180 // force rebuilding each time
185 // #pragma mark - RecentFilesMenu
188 RecentFilesMenu::RecentFilesMenu(const char* title
, BMessage
* openFileMessage
,
189 BMessage
* openFolderMessage
, BHandler
* target
, int32 maxItems
,
190 bool navMenuFolders
, const char* ofType
, const char* openedByAppSig
)
192 RecentItemsMenu(title
, openFileMessage
, target
, maxItems
),
193 openFolderMessage(openFolderMessage
)
195 fIterator
= new BRecentFilesList(maxItems
+ 10, navMenuFolders
,
196 ofType
, openedByAppSig
);
200 RecentFilesMenu::RecentFilesMenu(const char* title
, BMessage
* openFileMessage
,
201 BMessage
* openFolderMessage
, BHandler
* target
, int32 maxItems
,
202 bool navMenuFolders
, const char* ofTypeList
[], int32 ofTypeListCount
,
203 const char* openedByAppSig
)
205 RecentItemsMenu(title
, openFileMessage
, target
, maxItems
),
206 openFolderMessage(openFolderMessage
)
208 fIterator
= new BRecentFilesList(maxItems
+ 10, navMenuFolders
,
209 ofTypeList
, ofTypeListCount
, openedByAppSig
);
213 RecentFilesMenu::~RecentFilesMenu()
215 delete openFolderMessage
;
219 // #pragma mark - RecentFoldersMenu
222 RecentFoldersMenu::RecentFoldersMenu(const char* title
, BMessage
* openMessage
,
223 BHandler
* target
, int32 maxItems
, bool navMenuFolders
,
224 const char* openedByAppSig
)
226 RecentItemsMenu(title
, openMessage
, target
, maxItems
)
228 fIterator
= new BRecentFoldersList(maxItems
+ 10, navMenuFolders
,
233 // #pragma mark - RecentAppsMenu
236 RecentAppsMenu::RecentAppsMenu(const char* title
, BMessage
* openMessage
,
237 BHandler
* target
, int32 maxItems
)
239 RecentItemsMenu(title
, openMessage
, target
, maxItems
)
241 fIterator
= new BRecentAppsList(maxItems
);
245 // #pragma mark - BRecentItemsList
248 BRecentItemsList::BRecentItemsList(int32 maxItems
, bool navMenuFolders
)
251 fNavMenuFolders(navMenuFolders
)
254 // need the icon cache
260 BRecentItemsList::Rewind()
268 BRecentItemsList::GetNextMenuItem(const BMessage
* fileOpenInvokeMessage
,
269 const BMessage
* containerOpenInvokeMessage
, BHandler
* target
,
270 entry_ref
* currentItemRef
)
273 if (GetNextRef(&ref
) != B_OK
)
276 Model
model(&ref
, true);
277 if (model
.InitCheck() != B_OK
)
280 bool container
= false;
281 if (model
.IsSymLink()) {
283 Model
* newResolvedModel
= NULL
;
284 Model
* result
= model
.LinkTo();
286 if (result
== NULL
) {
287 newResolvedModel
= new Model(model
.EntryRef(), true, true);
289 if (newResolvedModel
->InitCheck() != B_OK
) {
290 // broken link, still can show though, bail
291 delete newResolvedModel
;
294 result
= newResolvedModel
;
296 BModelOpener
opener(result
);
297 // open the model, if it ain't open already
300 BNode
* resultNode
= result
->Node();
301 if (resultNode
!= NULL
) {
302 resultNode
->ReadAttr(kAttrPoseInfo
, B_RAW_TYPE
, 0,
303 &poseInfo
, sizeof(poseInfo
));
308 ref
= *result
->EntryRef();
309 container
= result
->IsContainer();
311 model
.SetLinkTo(result
);
313 ref
= *model
.EntryRef();
314 container
= model
.IsContainer();
317 // if user asked for it, return the current item ref
318 if (currentItemRef
!= NULL
)
319 *currentItemRef
= ref
;
322 if (container
&& containerOpenInvokeMessage
)
323 message
= new BMessage(*containerOpenInvokeMessage
);
324 else if (!container
&& fileOpenInvokeMessage
)
325 message
= new BMessage(*fileOpenInvokeMessage
);
327 message
= new BMessage(B_REFS_RECEIVED
);
329 message
->AddRef("refs", model
.EntryRef());
331 // Truncate the name if necessary
332 BString
truncatedString(model
.Name());
333 be_plain_font
->TruncateString(&truncatedString
, B_TRUNCATE_END
,
334 BNavMenu::GetMaxMenuWidth());
336 ModelMenuItem
* item
= NULL
;
337 if (!container
|| !fNavMenuFolders
)
338 item
= new ModelMenuItem(&model
, truncatedString
.String(), message
);
340 // add another nav menu item if it's a directory
341 BNavMenu
* menu
= new BNavMenu(truncatedString
.String(), message
->what
,
344 menu
->SetNavDir(&ref
);
345 item
= new ModelMenuItem(&model
, menu
);
346 item
->SetMessage(message
);
349 if (item
!= NULL
&& target
!= NULL
)
350 item
->SetTarget(target
);
357 BRecentItemsList::GetNextRef(entry_ref
* result
)
359 return fItems
.FindRef("refs", fIndex
++, result
);
363 // #pragma mark - BRecentFilesList
366 BRecentFilesList::BRecentFilesList(int32 maxItems
, bool navMenuFolders
,
367 const char* ofType
, const char* openedByAppSig
)
369 BRecentItemsList(maxItems
, navMenuFolders
),
373 fAppSig(openedByAppSig
)
378 BRecentFilesList::BRecentFilesList(int32 maxItems
, bool navMenuFolders
,
379 const char* ofTypeList
[], int32 ofTypeListCount
,
380 const char* openedByAppSig
)
382 BRecentItemsList(maxItems
, navMenuFolders
),
385 fTypeCount(ofTypeListCount
),
386 fAppSig(openedByAppSig
)
388 if (fTypeCount
> 0) {
389 fTypes
= new char *[ofTypeListCount
];
390 for (int32 index
= 0; index
< ofTypeListCount
; index
++)
391 fTypes
[index
] = strdup(ofTypeList
[index
]);
396 BRecentFilesList::~BRecentFilesList()
398 if (fTypeCount
> 0) {
399 for (int32 index
= 0; index
< fTypeCount
; index
++)
407 BRecentFilesList::GetNextRef(entry_ref
* ref
)
411 if (fTypes
!= NULL
) {
412 BRoster().GetRecentDocuments(&fItems
, fMaxItems
,
413 const_cast<const char**>(fTypes
),
414 fTypeCount
, fAppSig
.Length() ? fAppSig
.String() : NULL
);
416 BRoster().GetRecentDocuments(&fItems
, fMaxItems
,
417 fType
.Length() ? fType
.String() : NULL
,
418 fAppSig
.Length() ? fAppSig
.String() : NULL
);
423 return BRecentItemsList::GetNextRef(ref
);
428 BRecentFilesList::NewFileListMenu(const char* title
,
429 BMessage
* openFileMessage
, BMessage
* openFolderMessage
,
430 BHandler
* target
, int32 maxItems
, bool navMenuFolders
, const char* ofType
,
431 const char* openedByAppSig
)
433 return new RecentFilesMenu(title
, openFileMessage
,
434 openFolderMessage
, target
, maxItems
, navMenuFolders
, ofType
,
440 BRecentFilesList::NewFileListMenu(const char* title
,
441 BMessage
* openFileMessage
, BMessage
* openFolderMessage
,
442 BHandler
* target
, int32 maxItems
, bool navMenuFolders
,
443 const char* ofTypeList
[], int32 ofTypeListCount
,
444 const char* openedByAppSig
)
446 return new RecentFilesMenu(title
, openFileMessage
,
447 openFolderMessage
, target
, maxItems
, navMenuFolders
, ofTypeList
,
448 ofTypeListCount
, openedByAppSig
);
452 // #pragma mark - BRecentFoldersList
456 BRecentFoldersList::NewFolderListMenu(const char* title
,
457 BMessage
* openMessage
, BHandler
* target
, int32 maxItems
,
458 bool navMenuFolders
, const char* openedByAppSig
)
460 return new RecentFoldersMenu(title
, openMessage
, target
, maxItems
,
461 navMenuFolders
, openedByAppSig
);
465 BRecentFoldersList::BRecentFoldersList(int32 maxItems
, bool navMenuFolders
,
466 const char* openedByAppSig
)
468 BRecentItemsList(maxItems
, navMenuFolders
),
469 fAppSig(openedByAppSig
)
475 BRecentFoldersList::GetNextRef(entry_ref
* ref
)
479 BRoster().GetRecentFolders(&fItems
, fMaxItems
,
480 fAppSig
.Length() ? fAppSig
.String() : NULL
);
484 return BRecentItemsList::GetNextRef(ref
);
488 // #pragma mark - BRecentAppsList
491 BRecentAppsList::BRecentAppsList(int32 maxItems
)
493 BRecentItemsList(maxItems
, false)
499 BRecentAppsList::GetNextRef(entry_ref
* ref
)
503 BRoster().GetRecentApps(&fItems
, fMaxItems
);
506 return BRecentItemsList::GetNextRef(ref
);
511 BRecentAppsList::NewAppListMenu(const char* title
, BMessage
* openMessage
,
512 BHandler
* target
, int32 maxItems
)
514 return new RecentAppsMenu(title
, openMessage
, target
, maxItems
);