RemoteDrawingEngine: Reduce RP_READ_BITMAP result timeout.
[haiku.git] / src / kits / tracker / RecentItems.cpp
blob18c18b1db9801085f4096d0c28562615b25a3d24
1 /*
2 Open Tracker License
4 Terms and Conditions
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.
32 All rights reserved.
36 #include "RecentItems.h"
38 #include <Roster.h>
40 #include "Attributes.h"
41 #include "IconMenuItem.h"
42 #include "Model.h"
43 #include "NavMenu.h"
44 #include "PoseView.h"
45 #include "SlowMenu.h"
46 #include "Tracker.h"
47 #include "Utilities.h"
50 class RecentItemsMenu : public BSlowMenu {
51 public:
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();
61 protected:
62 virtual const BMessage* FileMessage()
64 return fTargetMesage;
67 virtual const BMessage* ContainerMessage()
69 return fTargetMesage;
72 BRecentItemsList* fIterator;
73 BMessage* fTargetMesage;
74 BHandler* fItemTarget;
75 int32 fCount;
76 int32 fSanityCount;
77 int32 fMaxCount;
81 class RecentFilesMenu : public RecentItemsMenu {
82 public:
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();
95 protected:
96 virtual const BMessage* ContainerMessage()
97 { return openFolderMessage; }
99 private:
100 BMessage* openFolderMessage;
104 class RecentFoldersMenu : public RecentItemsMenu {
105 public:
106 RecentFoldersMenu(const char* title, BMessage* openMessage,
107 BHandler* target, int32 maxItems, bool navMenuFolders,
108 const char* openedByAppSig);
112 class RecentAppsMenu : public RecentItemsMenu {
113 public:
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)
125 BSlowMenu(title),
126 fIterator(NULL),
127 fTargetMesage(openMessage),
128 fItemTarget(itemTarget),
129 fCount(-1),
130 fSanityCount(-1),
131 fMaxCount(maxItems)
136 RecentItemsMenu::~RecentItemsMenu()
138 delete fIterator;
139 delete fTargetMesage;
143 bool
144 RecentItemsMenu::AddNextItem()
146 BMenuItem* item = fIterator->GetNextMenuItem(FileMessage(),
147 ContainerMessage(), fItemTarget);
148 if (item != NULL) {
149 AddItem(item);
150 fCount++;
152 fSanityCount++;
154 return fCount < fMaxCount - 1 && (fSanityCount < fMaxCount + 20);
155 // fSanityCount is a hacky way of dealing with a lot of stale
156 // recent apps
160 bool
161 RecentItemsMenu::StartBuildingItemList()
163 // remove any preexisting items
164 int32 itemCount = CountItems();
165 while (itemCount--)
166 delete RemoveItem((int32)0);
168 fCount = 0;
169 fSanityCount = 0;
170 fIterator->Rewind();
172 return true;
176 void
177 RecentItemsMenu::ClearMenuBuildingState()
179 fMenuBuilt = false;
180 // force rebuilding each time
181 fIterator->Rewind();
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,
229 openedByAppSig);
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)
250 fMaxItems(maxItems),
251 fNavMenuFolders(navMenuFolders)
253 InitIconPreloader();
254 // need the icon cache
255 Rewind();
259 void
260 BRecentItemsList::Rewind()
262 fIndex = 0;
263 fItems.MakeEmpty();
267 BMenuItem*
268 BRecentItemsList::GetNextMenuItem(const BMessage* fileOpenInvokeMessage,
269 const BMessage* containerOpenInvokeMessage, BHandler* target,
270 entry_ref* currentItemRef)
272 entry_ref ref;
273 if (GetNextRef(&ref) != B_OK)
274 return NULL;
276 Model model(&ref, true);
277 if (model.InitCheck() != B_OK)
278 return NULL;
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;
292 result = NULL;
293 } else
294 result = newResolvedModel;
295 } else {
296 BModelOpener opener(result);
297 // open the model, if it ain't open already
299 PoseInfo poseInfo;
300 BNode* resultNode = result->Node();
301 if (resultNode != NULL) {
302 resultNode->ReadAttr(kAttrPoseInfo, B_RAW_TYPE, 0,
303 &poseInfo, sizeof(poseInfo));
306 result->CloseNode();
308 ref = *result->EntryRef();
309 container = result->IsContainer();
311 model.SetLinkTo(result);
312 } else {
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;
321 BMessage* message;
322 if (container && containerOpenInvokeMessage)
323 message = new BMessage(*containerOpenInvokeMessage);
324 else if (!container && fileOpenInvokeMessage)
325 message = new BMessage(*fileOpenInvokeMessage);
326 else
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);
339 else {
340 // add another nav menu item if it's a directory
341 BNavMenu* menu = new BNavMenu(truncatedString.String(), message->what,
342 target, 0);
344 menu->SetNavDir(&ref);
345 item = new ModelMenuItem(&model, menu);
346 item->SetMessage(message);
349 if (item != NULL && target != NULL)
350 item->SetTarget(target);
352 return item;
356 status_t
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),
370 fType(ofType),
371 fTypes(NULL),
372 fTypeCount(0),
373 fAppSig(openedByAppSig)
378 BRecentFilesList::BRecentFilesList(int32 maxItems, bool navMenuFolders,
379 const char* ofTypeList[], int32 ofTypeListCount,
380 const char* openedByAppSig)
382 BRecentItemsList(maxItems, navMenuFolders),
383 fType(NULL),
384 fTypes(NULL),
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++)
400 free(fTypes[index]);
401 delete[] fTypes;
406 status_t
407 BRecentFilesList::GetNextRef(entry_ref* ref)
409 if (fIndex == 0) {
410 // Lazy roster Get
411 if (fTypes != NULL) {
412 BRoster().GetRecentDocuments(&fItems, fMaxItems,
413 const_cast<const char**>(fTypes),
414 fTypeCount, fAppSig.Length() ? fAppSig.String() : NULL);
415 } else {
416 BRoster().GetRecentDocuments(&fItems, fMaxItems,
417 fType.Length() ? fType.String() : NULL,
418 fAppSig.Length() ? fAppSig.String() : NULL);
423 return BRecentItemsList::GetNextRef(ref);
427 BMenu*
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,
435 openedByAppSig);
439 BMenu*
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
455 BMenu*
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)
474 status_t
475 BRecentFoldersList::GetNextRef(entry_ref* ref)
477 if (fIndex == 0) {
478 // Lazy roster Get
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)
498 status_t
499 BRecentAppsList::GetNextRef(entry_ref* ref)
501 if (fIndex == 0) {
502 // Lazy roster Get
503 BRoster().GetRecentApps(&fItems, fMaxItems);
506 return BRecentItemsList::GetNextRef(ref);
510 BMenu*
511 BRecentAppsList::NewAppListMenu(const char* title, BMessage* openMessage,
512 BHandler* target, int32 maxItems)
514 return new RecentAppsMenu(title, openMessage, target, maxItems);