btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / kits / tracker / FavoritesMenu.cpp
blob1763589b432bfbaec048d3c8e1f400bab6dafd50
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 "FavoritesMenu.h"
38 #include <compat/sys/stat.h>
40 #include <Application.h>
41 #include <Catalog.h>
42 #include <FindDirectory.h>
43 #include <FilePanel.h>
44 #include <Locale.h>
45 #include <Message.h>
46 #include <Path.h>
47 #include <Query.h>
48 #include <Roster.h>
50 #include <functional>
51 #include <algorithm>
53 #include "IconMenuItem.h"
54 #include "PoseView.h"
55 #include "QueryPoseView.h"
56 #include "Tracker.h"
57 #include "Utilities.h"
58 #include "VirtualDirectoryEntryList.h"
61 #undef B_TRANSLATION_CONTEXT
62 #define B_TRANSLATION_CONTEXT "FavoritesMenu"
65 // #pragma mark - FavoritesMenu
68 FavoritesMenu::FavoritesMenu(const char* title, BMessage* openFolderMessage,
69 BMessage* openFileMessage, const BMessenger &target,
70 bool isSavePanel, BRefFilter* filter)
72 BSlowMenu(title),
73 fOpenFolderMessage(openFolderMessage),
74 fOpenFileMessage(openFileMessage),
75 fTarget(target),
76 fState(kStart),
77 fIndex(-1),
78 fSectionItemCount(-1),
79 fAddedSeparatorForSection(false),
80 fContainer(NULL),
81 fItemList(NULL),
82 fInitialItemCount(0),
83 fIsSavePanel(isSavePanel),
84 fRefFilter(filter)
89 FavoritesMenu::~FavoritesMenu()
91 delete fOpenFolderMessage;
92 delete fOpenFileMessage;
93 delete fContainer;
97 void
98 FavoritesMenu::SetRefFilter(BRefFilter* filter)
100 fRefFilter = filter;
104 bool
105 FavoritesMenu::StartBuildingItemList()
107 // initialize the menu building state
109 if (fInitialItemCount == 0)
110 fInitialItemCount = CountItems();
111 else {
112 // strip the old items so we can add new fresh ones
113 int32 count = CountItems() - fInitialItemCount;
114 // keep the items that were added by the FavoritesMenu creator
115 while (count--)
116 delete RemoveItem(fInitialItemCount);
119 fUniqueRefCheck.clear();
120 fState = kStart;
121 return true;
125 bool
126 FavoritesMenu::AddNextItem()
128 // run the next chunk of code for a given item adding state
130 if (fState == kStart) {
131 fState = kAddingFavorites;
132 fSectionItemCount = 0;
133 fAddedSeparatorForSection = false;
134 // set up adding the GoTo menu items
136 try {
137 BPath path;
138 ThrowOnError(find_directory(B_USER_SETTINGS_DIRECTORY,
139 &path, true));
140 path.Append(kGoDirectory);
141 mkdir(path.Path(), 0777);
143 BEntry entry(path.Path());
144 Model startModel(&entry, true);
145 ThrowOnInitCheckError(&startModel);
147 if (!startModel.IsContainer())
148 throw B_ERROR;
150 if (startModel.IsQuery())
151 fContainer = new QueryEntryListCollection(&startModel);
152 else if (startModel.IsVirtualDirectory())
153 fContainer = new VirtualDirectoryEntryList(&startModel);
154 else {
155 BDirectory* directory
156 = dynamic_cast<BDirectory*>(startModel.Node());
157 if (directory != NULL)
158 fContainer = new DirectoryEntryList(*directory);
161 ThrowOnInitCheckError(fContainer);
162 ThrowOnError(fContainer->Rewind());
163 } catch (...) {
164 delete fContainer;
165 fContainer = NULL;
169 if (fState == kAddingFavorites) {
170 entry_ref ref;
171 if (fContainer != NULL && fContainer->GetNextRef(&ref) == B_OK) {
172 Model model(&ref, true);
173 if (model.InitCheck() != B_OK)
174 return true;
176 if (!ShouldShowModel(&model))
177 return true;
179 BMenuItem* item = BNavMenu::NewModelItem(&model,
180 model.IsDirectory() ? fOpenFolderMessage : fOpenFileMessage,
181 fTarget);
183 if (item == NULL)
184 return true;
186 item->SetLabel(ref.name);
187 // this is the name of the link in the Go dir
189 if (!fAddedSeparatorForSection) {
190 fAddedSeparatorForSection = true;
191 AddItem(new TitledSeparatorItem(B_TRANSLATE("Favorites")));
193 fUniqueRefCheck.push_back(*model.EntryRef());
194 AddItem(item);
195 fSectionItemCount++;
197 return true;
200 // done with favorites, set up for adding recent files
201 fState = kAddingFiles;
203 fAddedSeparatorForSection = false;
205 app_info info;
206 be_app->GetAppInfo(&info);
207 fItems.MakeEmpty();
209 int32 apps, docs, folders;
210 TrackerSettings().RecentCounts(&apps, &docs, &folders);
212 BRoster().GetRecentDocuments(&fItems, docs, NULL, info.signature);
213 fIndex = 0;
214 fSectionItemCount = 0;
217 if (fState == kAddingFiles) {
218 // if this is a Save panel, not an Open panel
219 // then don't add the recent documents
220 if (!fIsSavePanel) {
221 for (;;) {
222 entry_ref ref;
223 if (fItems.FindRef("refs", fIndex++, &ref) != B_OK)
224 break;
226 Model model(&ref, true);
227 if (model.InitCheck() != B_OK)
228 return true;
230 if (!ShouldShowModel(&model))
231 return true;
233 BMenuItem* item = BNavMenu::NewModelItem(&model,
234 fOpenFileMessage, fTarget);
235 if (item) {
236 if (!fAddedSeparatorForSection) {
237 fAddedSeparatorForSection = true;
238 AddItem(new TitledSeparatorItem(
239 B_TRANSLATE("Recent documents")));
241 AddItem(item);
242 fSectionItemCount++;
243 return true;
248 // done with recent files, set up for adding recent folders
249 fState = kAddingFolders;
251 fAddedSeparatorForSection = false;
253 app_info info;
254 be_app->GetAppInfo(&info);
255 fItems.MakeEmpty();
257 int32 apps, docs, folders;
258 TrackerSettings().RecentCounts(&apps, &docs, &folders);
260 BRoster().GetRecentFolders(&fItems, folders, info.signature);
261 fIndex = 0;
264 if (fState == kAddingFolders) {
265 for (;;) {
266 entry_ref ref;
267 if (fItems.FindRef("refs", fIndex++, &ref) != B_OK)
268 break;
270 // don't add folders that are already in the GoTo section
271 if (find_if(fUniqueRefCheck.begin(), fUniqueRefCheck.end(),
272 bind2nd(std::equal_to<entry_ref>(), ref))
273 != fUniqueRefCheck.end()) {
274 continue;
277 Model model(&ref, true);
278 if (model.InitCheck() != B_OK)
279 return true;
281 if (!ShouldShowModel(&model))
282 return true;
284 BMenuItem* item = BNavMenu::NewModelItem(&model,
285 fOpenFolderMessage, fTarget, true);
286 if (item != NULL) {
287 if (!fAddedSeparatorForSection) {
288 fAddedSeparatorForSection = true;
289 AddItem(new TitledSeparatorItem(
290 B_TRANSLATE("Recent folders")));
292 AddItem(item);
293 item->SetEnabled(true);
294 // BNavMenu::NewModelItem returns a disabled item here -
295 // need to fix this in BNavMenu::NewModelItem
297 return true;
302 return false;
306 void
307 FavoritesMenu::DoneBuildingItemList()
309 SetTargetForItems(fTarget);
313 void
314 FavoritesMenu::ClearMenuBuildingState()
316 delete fContainer;
317 fContainer = NULL;
318 fState = kDone;
320 // force the menu to get rebuilt each time
321 fMenuBuilt = false;
325 bool
326 FavoritesMenu::ShouldShowModel(const Model* model)
328 if (fIsSavePanel && model->IsFile())
329 return false;
331 if (!fRefFilter || model->Node() == NULL)
332 return true;
334 struct stat_beos statBeOS;
335 convert_to_stat_beos(model->StatBuf(), &statBeOS);
337 return fRefFilter->Filter(model->EntryRef(), model->Node(), &statBeOS,
338 model->MimeType());
342 // #pragma mark - RecentsMenu
345 RecentsMenu::RecentsMenu(const char* name, int32 which, uint32 what,
346 BHandler* target)
348 BNavMenu(name, what, target),
349 fWhich(which),
350 fRecentsCount(0),
351 fItemIndex(0)
353 int32 applications;
354 int32 documents;
355 int32 folders;
356 TrackerSettings().RecentCounts(&applications,&documents,&folders);
358 if (fWhich == 0)
359 fRecentsCount = documents;
360 else if (fWhich == 1)
361 fRecentsCount = applications;
362 else if (fWhich == 2)
363 fRecentsCount = folders;
367 void
368 RecentsMenu::DetachedFromWindow()
371 // BNavMenu::DetachedFromWindow sets the TypesList to NULL
373 BMenu::DetachedFromWindow();
377 bool
378 RecentsMenu::StartBuildingItemList()
380 int32 count = CountItems()-1;
381 for (int32 index = count; index >= 0; index--) {
382 BMenuItem* item = ItemAt(index);
383 ASSERT(item);
385 RemoveItem(index);
386 delete item;
389 // !! note: don't call inherited from here
390 // the navref is not set for this menu
391 // but it still needs to be a draggable navmenu
392 // simply return true so that AddNextItem is called
394 // return BNavMenu::StartBuildingItemList();
395 return true;
399 bool
400 RecentsMenu::AddNextItem()
402 if (fRecentsCount > 0 && AddRecents(fRecentsCount))
403 return true;
405 fItemIndex = 0;
406 return false;
410 bool
411 RecentsMenu::AddRecents(int32 count)
413 if (fItemIndex == 0) {
414 fRecentList.MakeEmpty();
415 BRoster roster;
417 switch(fWhich) {
418 case 0:
419 roster.GetRecentDocuments(&fRecentList, count);
420 break;
421 case 1:
422 roster.GetRecentApps(&fRecentList, count);
423 break;
424 case 2:
425 roster.GetRecentFolders(&fRecentList, count);
426 break;
427 default:
428 return false;
429 break;
432 for (;;) {
433 entry_ref ref;
434 if (fRecentList.FindRef("refs", fItemIndex++, &ref) != B_OK)
435 break;
437 if (ref.name != NULL && strlen(ref.name) > 0) {
438 Model model(&ref, true);
439 ModelMenuItem* item = BNavMenu::NewModelItem(&model,
440 new BMessage(fMessage.what),
441 Target(), false, NULL, TypesList());
443 if (item != NULL) {
444 AddItem(item);
446 // return true so that we know to reenter this list
447 return true;
450 return true;
455 // return false if we are done with this list
457 return false;
461 void
462 RecentsMenu::DoneBuildingItemList()
465 // !! note: don't call inherited here
466 // the object list is not built
467 // and this list does not need to be sorted
468 // BNavMenu::DoneBuildingItemList();
471 if (CountItems() <= 0) {
472 BMenuItem* item = new BMenuItem(B_TRANSLATE("<No recent items>"), 0);
473 item->SetEnabled(false);
474 AddItem(item);
475 } else
476 SetTargetForItems(Target());
480 void
481 RecentsMenu::ClearMenuBuildingState()
483 fMenuBuilt = false;
484 BNavMenu::ClearMenuBuildingState();