Пример #1
0
ModelMenuItem::ModelMenuItem(const Model* model, BMenu* menu, bool drawText,
	bool extraPad)
	:
	BMenuItem(menu),
	fModel(*model),
	fHeightDelta(0),
	fDrawText(drawText),
	fExtraPad(extraPad)
{
	ThrowOnInitCheckError(&fModel);
	// ModelMenuItem is used in synchronously invoked menus, make sure
	// we invoke with a timeout
	SetTimeout(kSynchMenuInvokeTimeout);
}
Пример #2
0
ModelMenuItem::ModelMenuItem(const Model* model, const char* title,
	BMessage* message, char shortcut, uint32 modifiers,
	bool drawText, bool extraPad)
	:
	BMenuItem(title, message, shortcut, modifiers),
	fModel(*model),
	fHeightDelta(0),
	fDrawText(drawText),
	fExtraPad(extraPad)
{
	ThrowOnInitCheckError(&fModel);
	// The 'fExtraPad' field is used to when this menu item is added to
	// a menubar instead of a menu. Menus and MenuBars space out items
	// differently (more space around items in a menu). This class wants
	// to be able to space item the same, no matter where they are. The
	// fExtraPad field allows for that.

	if (model->IsRoot())
		SetLabel(model->Name());

	// ModelMenuItem is used in synchronously invoked menus, make sure
	// we invoke with a timeout
	SetTimeout(kSynchMenuInvokeTimeout);
}
Пример #3
0
bool
FavoritesMenu::AddNextItem()
{
	// run the next chunk of code for a given item adding state

	if (fState == kStart) {
		fState = kAddingFavorites;
		fSectionItemCount = 0;
		fAddedSeparatorForSection = false;
		// set up adding the GoTo menu items

		try {
			BPath path;
			ThrowOnError(find_directory(B_USER_SETTINGS_DIRECTORY,
				&path, true));
			path.Append(kGoDirectory);
			mkdir(path.Path(), 0777);

			BEntry entry(path.Path());
			Model startModel(&entry, true);
			ThrowOnInitCheckError(&startModel);

			if (!startModel.IsContainer())
				throw B_ERROR;

			if (startModel.IsQuery())
				fContainer = new QueryEntryListCollection(&startModel);
			else
				fContainer = new DirectoryEntryList(*dynamic_cast<BDirectory*>
					(startModel.Node()));

			ThrowOnInitCheckError(fContainer);
			ThrowOnError( fContainer->Rewind() );

		} catch (...) {
			delete fContainer;
			fContainer = NULL;
		}
	}


	if (fState == kAddingFavorites) {
		entry_ref ref;
		if (fContainer
			&& fContainer->GetNextRef(&ref) == B_OK) {
			Model model(&ref, true);
			if (model.InitCheck() != B_OK)
				return true;

			if (!ShouldShowModel(&model))
				return true;

			BMenuItem* item = BNavMenu::NewModelItem(&model,
				model.IsDirectory() ? fOpenFolderMessage : fOpenFileMessage,
				fTarget);
				
			if (item == NULL)
				return true;

			item->SetLabel(ref.name);
				// this is the name of the link in the Go dir

			if (!fAddedSeparatorForSection) {
				fAddedSeparatorForSection = true;
				AddItem(new TitledSeparatorItem(B_TRANSLATE("Favorites")));
			}
			fUniqueRefCheck.push_back(*model.EntryRef());
			AddItem(item);
			fSectionItemCount++;
			return true;
		}

		// done with favorites, set up for adding recent files
		fState = kAddingFiles;

		fAddedSeparatorForSection = false;

		app_info info;
		be_app->GetAppInfo(&info);
		fItems.MakeEmpty();

		int32 apps, docs, folders;
		TrackerSettings().RecentCounts(&apps, &docs, &folders);

		BRoster().GetRecentDocuments(&fItems, docs, NULL, info.signature);
		fIndex = 0;
		fSectionItemCount = 0;
	}

	if (fState == kAddingFiles) {
		//	if this is a Save panel, not an Open panel
		//	then don't add the recent documents
		if (!fIsSavePanel) {
			for (;;) {
				entry_ref ref;
				if (fItems.FindRef("refs", fIndex++, &ref) != B_OK)
					break;

				Model model(&ref, true);
				if (model.InitCheck() != B_OK)
					return true;

				if (!ShouldShowModel(&model))
					return true;

				BMenuItem* item = BNavMenu::NewModelItem(&model,
					fOpenFileMessage, fTarget);
				if (item) {
					if (!fAddedSeparatorForSection) {
						fAddedSeparatorForSection = true;
						AddItem(new TitledSeparatorItem(
							B_TRANSLATE("Recent documents")));
					}
					AddItem(item);
					fSectionItemCount++;
					return true;
				}
			}
		}

		// done with recent files, set up for adding recent folders
		fState = kAddingFolders;

		fAddedSeparatorForSection = false;

		app_info info;
		be_app->GetAppInfo(&info);
		fItems.MakeEmpty();

		int32 apps, docs, folders;
		TrackerSettings().RecentCounts(&apps, &docs, &folders);

		BRoster().GetRecentFolders(&fItems, folders, info.signature);
		fIndex = 0;
	}

	if (fState == kAddingFolders) {
		for (;;) {
			entry_ref ref;
			if (fItems.FindRef("refs", fIndex++, &ref) != B_OK)
				break;

			// don't add folders that are already in the GoTo section
			if (find_if(fUniqueRefCheck.begin(), fUniqueRefCheck.end(),
				bind2nd(std::equal_to<entry_ref>(), ref))
					!= fUniqueRefCheck.end()) {
				continue;
			}

			Model model(&ref, true);
			if (model.InitCheck() != B_OK)
				return true;

			if (!ShouldShowModel(&model))
				return true;

			BMenuItem* item = BNavMenu::NewModelItem(&model,
				fOpenFolderMessage, fTarget, true);
			if (item) {
				if (!fAddedSeparatorForSection) {
					fAddedSeparatorForSection = true;
					AddItem(new TitledSeparatorItem(
						B_TRANSLATE("Recent folders")));
				}
				AddItem(item);
				item->SetEnabled(true);
					// BNavMenu::NewModelItem returns a disabled item here -
					// need to fix this in BNavMenu::NewModelItem
				return true;
			}
		}
	}
	return false;
}
Пример #4
0
void
BDirMenu::Populate(const BEntry* startEntry, BWindow* originatingWindow,
	bool includeStartEntry, bool select, bool reverse, bool addShortcuts,
	bool navMenuEntries)
{
	try {
		if (!startEntry)
			throw (status_t)B_ERROR;

		Model model(startEntry);
		ThrowOnInitCheckError(&model);

		ModelMenuItem* menu = new ModelMenuItem(&model, this, true, true);

		if (fMenuBar)
			fMenuBar->AddItem(menu);

		BEntry entry(*startEntry);

		bool showDesktop, showDisksIcon;
		{
			TrackerSettings settings;
			showDesktop = settings.DesktopFilePanelRoot();
			showDisksIcon = settings.ShowDisksIcon();
		}

		// might start one level above startEntry
		if (!includeStartEntry) {
			BDirectory parent;
			BDirectory dir(&entry);

			if (!showDesktop && dir.InitCheck() == B_OK
				&& dir.IsRootDirectory()) {
				// if we're at the root directory skip "mnt" and
				// go straight to "/"
				parent.SetTo("/");
			} else
				entry.GetParent(&parent);

			parent.GetEntry(&entry);
		}

		BDirectory desktopDir;
		FSGetDeskDir(&desktopDir);
		BEntry desktopEntry;
		desktopDir.GetEntry(&desktopEntry);

		for (;;) {
			BNode node(&entry);
			ThrowOnInitCheckError(&node);

			PoseInfo info;
			ReadAttrResult result = ReadAttr(&node, kAttrPoseInfo,
				kAttrPoseInfoForeign, B_RAW_TYPE, 0, &info, sizeof(PoseInfo),
				&PoseInfo::EndianSwap);

			BDirectory parent;
			entry.GetParent(&parent);

			bool hitRoot = false;

			BDirectory dir(&entry);
			if (!showDesktop && dir.InitCheck() == B_OK
				&& dir.IsRootDirectory()) {
				// if we're at the root directory skip "mnt" and
				// go straight to "/"
				hitRoot = true;
				parent.SetTo("/");
			}

			if (showDesktop) {
				BEntry root("/");
				// warp from "/" to Desktop properly
				if (entry == root) {
					if (showDisksIcon)
						AddDisksIconToMenu(reverse);
					entry = desktopEntry;
				}

				if (entry == desktopEntry)
					hitRoot = true;
			}

			if (result == kReadAttrFailed || !info.fInvisible
				|| (showDesktop && desktopEntry == entry)) {
				AddItemToDirMenu(&entry, originatingWindow, reverse,
					addShortcuts, navMenuEntries);
			}

			if (hitRoot) {
				if (!showDesktop && showDisksIcon && *startEntry != "/")
					AddDisksIconToMenu(reverse);
				break;
			}

			parent.GetEntry(&entry);
		}

		// select last item in menu
		if (!select)
			return;

		ModelMenuItem* item
			= dynamic_cast<ModelMenuItem*>(ItemAt(CountItems() - 1));
		if (item) {
			item->SetMarked(true);
			if (menu) {
				entry.SetTo(item->TargetModel()->EntryRef());
				ThrowOnError(menu->SetEntry(&entry));
			}
		}
	} catch (status_t err) {
		PRINT(("BDirMenu::Populate: caught error %s\n", strerror(err)));
		if (!CountItems()) {
			BString error;
			error << "Error [" << strerror(err) << "] populating menu";
			AddItem(new BMenuItem(error.String(), 0));
		}
	}
}