Beispiel #1
0
void CharismaWindow::Minimize(bool minimize)
{
	const float margin=4.0f;
	BRect r;
	
	// en réalité, minimize est ignoré
	
	if(!isminim){
		menubar->Hide();
		setupview->MoveTo(B_ORIGIN);
		modemenu->MoveTo(margin,margin);
	
		r=modemenu->Frame();
		ResizeTo(r.right+margin,r.bottom+margin);
		
		SetLook(B_MODAL_WINDOW_LOOK);

		isminim=1;
	}else{
		menubar->Show();
		setupview->MoveTo(0,menubar->Frame().bottom);
		modemenu->MoveTo(10.0f,10.0f);

		r=setupview->Frame();
		ResizeTo(r.right,r.bottom);

		SetLook(B_TITLED_WINDOW_LOOK);

		isminim=0;
	}
}
Beispiel #2
0
FindWindow::FindWindow(BRect _rect, BMessage& previous, BMessenger& target,
		const BMessage* settings)
	: BWindow(_rect, B_TRANSLATE("Find"), B_TITLED_WINDOW,
		B_ASYNCHRONOUS_CONTROLS | B_CLOSE_ON_ESCAPE),
	fTarget(target)
{
	BView* view = new BView(Bounds(), "main", B_FOLLOW_ALL, 0);
	view->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
	AddChild(view);

	int8 mode = kAsciiMode;
	if (previous.FindInt8("find_mode", &mode) != B_OK && settings != NULL)
		settings->FindInt8("find_mode", &mode);

	// add the top widgets

	fMenu = new BPopUpMenu("mode");
	BMessage* message;
	BMenuItem* item;
	fMenu->AddItem(item = new BMenuItem(B_TRANSLATE("Text"),
		message = new BMessage(kMsgFindMode)));
	message->AddInt8("mode", kAsciiMode);
	if (mode == kAsciiMode)
		item->SetMarked(true);
	fMenu->AddItem(item = new BMenuItem(B_TRANSLATE_COMMENT("Hexadecimal", 
		"A menu item, as short as possible, noun is recommended if it is "
		"shorter than adjective."), message = new BMessage(kMsgFindMode)));
	message->AddInt8("mode", kHexMode);
	if (mode == kHexMode)
		item->SetMarked(true);

	BRect rect = Bounds().InsetByCopy(5, 5);
	BMenuField* menuField = new BMenuField(rect, B_EMPTY_STRING,
		B_TRANSLATE("Mode:"), fMenu, B_FOLLOW_LEFT | B_FOLLOW_TOP);
	menuField->SetDivider(menuField->StringWidth(menuField->Label()) + 8);
	menuField->ResizeToPreferred();
	view->AddChild(menuField);

	// add the bottom widgets

	BButton* button = new BButton(rect, B_EMPTY_STRING, B_TRANSLATE("Find"),
		new BMessage(kMsgStartFind), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
	button->MakeDefault(true);
	button->ResizeToPreferred();
	button->MoveTo(rect.right - button->Bounds().Width(),
		rect.bottom - button->Bounds().Height());
	view->AddChild(button);

	fCaseCheckBox = new BCheckBox(rect, B_EMPTY_STRING, B_TRANSLATE("Case sensitive"),
		NULL, B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
	fCaseCheckBox->ResizeToPreferred();
	fCaseCheckBox->MoveTo(5, button->Frame().top);
	bool caseSensitive;
	if (previous.FindBool("case_sensitive", &caseSensitive) != B_OK) {
		if (settings == NULL
			|| settings->FindBool("case_sensitive", &caseSensitive) != B_OK)
			caseSensitive = true;
	}
	fCaseCheckBox->SetValue(caseSensitive);
	view->AddChild(fCaseCheckBox);

	// and now those inbetween

	rect.top = menuField->Frame().bottom + 5;
	rect.bottom = fCaseCheckBox->Frame().top - 8;
	rect.InsetBy(2, 2);
	fTextView = new FindTextView(rect, B_EMPTY_STRING,
		rect.OffsetToCopy(B_ORIGIN).InsetByCopy(3, 3), B_FOLLOW_ALL);
	fTextView->SetWordWrap(true);
	fTextView->SetMode((find_mode)mode);
	fTextView->SetData(previous);

	BScrollView* scrollView = new BScrollView("scroller", fTextView,
		B_FOLLOW_ALL, B_WILL_DRAW, false, false);
	view->AddChild(scrollView);

	ResizeTo(290, button->Frame().Height() * 3 + 30);

	SetSizeLimits(fCaseCheckBox->Bounds().Width() + button->Bounds().Width()
			+ 20, 32768, button->Frame().Height() * 3 + 10, 32768);
}
ApplicationTypeWindow::ApplicationTypeWindow(BPoint position, const BEntry& entry)
	: BWindow(BRect(0.0f, 0.0f, 250.0f, 340.0f).OffsetBySelf(position),
		"Application Type", B_TITLED_WINDOW,
		B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS),
	fChangedProperties(0)
{
	// add the menu

	BMenuBar* menuBar = new BMenuBar(BRect(0, 0, 0, 0), NULL);
	AddChild(menuBar);

	BMenu* menu = new BMenu("File");
	fSaveMenuItem = new BMenuItem("Save", new BMessage(kMsgSave), 'S');
	fSaveMenuItem->SetEnabled(false);
	menu->AddItem(fSaveMenuItem);
	BMenuItem* item;
	menu->AddItem(item = new BMenuItem("Save into resource file" B_UTF8_ELLIPSIS,
		NULL));
	item->SetEnabled(false);

	menu->AddSeparatorItem();
	menu->AddItem(new BMenuItem("Close", new BMessage(B_QUIT_REQUESTED),
		'W', B_COMMAND_KEY));
	menuBar->AddItem(menu);

	// Top view and signature

	BRect rect = Bounds();
	rect.top = menuBar->Bounds().Height() + 1.0f;
	BView* topView = new BView(rect, NULL, B_FOLLOW_ALL, B_WILL_DRAW);
	topView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
	AddChild(topView);

	rect = topView->Bounds().InsetByCopy(8.0f, 8.0f);
	fSignatureControl = new BTextControl(rect, "signature", "Signature:", NULL,
		new BMessage(kMsgSignatureChanged), B_FOLLOW_LEFT_RIGHT);
	fSignatureControl->SetModificationMessage(
		new BMessage(kMsgSignatureChanged));
	fSignatureControl->SetDivider(fSignatureControl->StringWidth(
		fSignatureControl->Label()) + 4.0f);
	float width, height;
	fSignatureControl->GetPreferredSize(&width, &height);
	fSignatureControl->ResizeTo(rect.Width(), height);
	topView->AddChild(fSignatureControl);

	// filter out invalid characters that can't be part of a MIME type name
	BTextView* textView = fSignatureControl->TextView();
	textView->SetMaxBytes(B_MIME_TYPE_LENGTH);
	const char* disallowedCharacters = "<>@,;:\"()[]?=";
	for (int32 i = 0; disallowedCharacters[i]; i++) {
		textView->DisallowChar(disallowedCharacters[i]);
	}

	// "Application Flags" group

	BFont font(be_bold_font);
	font_height fontHeight;
	font.GetHeight(&fontHeight);

	width = font.StringWidth("Icon") + 16.0f;
	if (width < B_LARGE_ICON + 16.0f)
		width = B_LARGE_ICON + 16.0f;

	rect.top = fSignatureControl->Frame().bottom + 4.0f;
	rect.bottom = rect.top + 100.0f;
	rect.right -= width + 8.0f;
	BBox* box = new BBox(rect, NULL, B_FOLLOW_LEFT_RIGHT);
	topView->AddChild(box);

	fFlagsCheckBox = new BCheckBox(rect, "flags", "Application flags",
		new BMessage(kMsgToggleAppFlags));
	fFlagsCheckBox->SetValue(B_CONTROL_ON);
	fFlagsCheckBox->ResizeToPreferred();
	box->SetLabel(fFlagsCheckBox);

	rect.top = fFlagsCheckBox->Bounds().Height() + 4.0f;
	fSingleLaunchButton = new BRadioButton(rect, "single", "Single launch",
		new BMessage(kMsgAppFlagsChanged));
	fSingleLaunchButton->ResizeToPreferred();
	box->AddChild(fSingleLaunchButton);

	rect.OffsetBy(0.0f, fSingleLaunchButton->Bounds().Height() + 0.0f);
	fMultipleLaunchButton = new BRadioButton(rect, "multiple",
		"Multiple launch", new BMessage(kMsgAppFlagsChanged));
	fMultipleLaunchButton->ResizeToPreferred();
	box->AddChild(fMultipleLaunchButton);

	rect.OffsetBy(0.0f, fSingleLaunchButton->Bounds().Height() + 0.0f);
	fExclusiveLaunchButton = new BRadioButton(rect, "exclusive",
		"Exclusive launch", new BMessage(kMsgAppFlagsChanged));
	fExclusiveLaunchButton->ResizeToPreferred();
	box->AddChild(fExclusiveLaunchButton);

	rect.top = fSingleLaunchButton->Frame().top;
	rect.left = fExclusiveLaunchButton->Frame().right + 4.0f;
	fArgsOnlyCheckBox = new BCheckBox(rect, "args only", "Args only",
		new BMessage(kMsgAppFlagsChanged));
	fArgsOnlyCheckBox->ResizeToPreferred();
	box->AddChild(fArgsOnlyCheckBox);

	rect.top += fArgsOnlyCheckBox->Bounds().Height();
	fBackgroundAppCheckBox = new BCheckBox(rect, "background",
		"Background app", new BMessage(kMsgAppFlagsChanged));
	fBackgroundAppCheckBox->ResizeToPreferred();
	box->AddChild(fBackgroundAppCheckBox);

	box->ResizeTo(box->Bounds().Width(),
		fExclusiveLaunchButton->Frame().bottom + 8.0f);

	// "Icon" group

	rect = box->Frame();
#ifdef __ANTARES__
	rect.top += box->TopBorderOffset();
#endif
	rect.left = rect.right + 8.0f;
	rect.right += width + 8.0f;
	float iconBoxWidth = rect.Width();
	box = new BBox(rect, NULL, B_FOLLOW_RIGHT | B_FOLLOW_TOP);
	box->SetLabel("Icon");
#ifdef __ANTARES__
	box->MoveBy(0.0f, -box->TopBorderOffset());
	box->ResizeBy(0.0f, box->TopBorderOffset());
#endif
	topView->AddChild(box);

	rect = BRect(8.0f, 0.0f, 7.0f + B_LARGE_ICON, B_LARGE_ICON - 1.0f);
#ifdef __ANTARES__
	rect.OffsetBy(0.0f, (box->Bounds().Height() + box->TopBorderOffset()
		- rect.Height()) / 2.0f);
#else
	rect.OffsetBy(0.0f, (box->Bounds().Height() - rect.Height()) / 2.0f);
#endif
	if (rect.top < fontHeight.ascent + fontHeight.descent + 4.0f)
		rect.top = fontHeight.ascent + fontHeight.descent + 4.0f;
	fIconView = new IconView(rect, "icon");
	fIconView->SetModificationMessage(new BMessage(kMsgIconChanged));
	box->AddChild(fIconView);

	// "Supported Types" group

	rect.top = box->Frame().bottom + 8.0f;
	rect.bottom = rect.top + box->Bounds().Height();
	rect.left = 8.0f;
	rect.right = Bounds().Width() - 8.0f;
	BBox* typeBox = new BBox(rect, NULL, B_FOLLOW_LEFT_RIGHT);
	typeBox->SetLabel("Supported types");
	topView->AddChild(typeBox);

	rect = typeBox->Bounds().InsetByCopy(8.0f, 6.0f);
	rect.top += ceilf(fontHeight.ascent);
	fAddTypeButton = new BButton(rect, "add type", "Add" B_UTF8_ELLIPSIS,
		new BMessage(kMsgAddType), B_FOLLOW_RIGHT);
	fAddTypeButton->ResizeToPreferred();
	fAddTypeButton->MoveBy(rect.right - fAddTypeButton->Bounds().Width()
		- B_LARGE_ICON - 16.0f, 0.0f);
	typeBox->AddChild(fAddTypeButton);

	rect = fAddTypeButton->Frame();
	rect.OffsetBy(0, rect.Height() + 4.0f);
	fRemoveTypeButton = new BButton(rect, "remove type", "Remove",
		new BMessage(kMsgRemoveType), B_FOLLOW_RIGHT);
	typeBox->AddChild(fRemoveTypeButton);

	rect.right = rect.left - 10.0f - B_V_SCROLL_BAR_WIDTH;
	rect.left = 10.0f;
	rect.top = 8.0f + ceilf(fontHeight.ascent);
	rect.bottom -= 2.0f;
		// take scrollview border into account
	fTypeListView = new SupportedTypeListView(rect, "type listview",
		B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL);
	fTypeListView->SetSelectionMessage(new BMessage(kMsgTypeSelected));

	BScrollView* scrollView = new BScrollView("type scrollview", fTypeListView,
		B_FOLLOW_ALL, B_FRAME_EVENTS | B_WILL_DRAW, false, true);

	typeBox->ResizeTo(typeBox->Bounds().Width(), fRemoveTypeButton->Frame().bottom + 8.0f);
	typeBox->AddChild(scrollView);

	rect.left = fRemoveTypeButton->Frame().right + 8.0f;
#ifdef __ANTARES__
	rect.top = (box->Bounds().Height() + box->TopBorderOffset() - B_LARGE_ICON) / 2.0f;
#else
	rect.top = (box->Bounds().Height() - B_LARGE_ICON) / 2.0f;
#endif
	rect.right = rect.left + B_LARGE_ICON - 1.0f;
	rect.bottom = rect.top + B_LARGE_ICON - 1.0f;
	fTypeIconView = new IconView(rect, "type icon", B_FOLLOW_RIGHT | B_FOLLOW_TOP);
	fTypeIconView->SetModificationMessage(new BMessage(kMsgTypeIconsChanged));
	typeBox->AddChild(fTypeIconView);

	// "Version Info" group

	rect.top = typeBox->Frame().bottom + 8.0f;
	rect.bottom = rect.top + typeBox->Bounds().Height();
	rect.left = 8.0f;
	rect.right = Bounds().Width() - 8.0f;
	box = new BBox(rect, NULL, B_FOLLOW_LEFT_RIGHT);
		// the resizing mode will later also be set to B_FOLLOW_BOTTOM
	box->SetLabel("Version info");
	topView->AddChild(box);

	BMenuField* menuField;
#if 0
	BPopUpMenu *popUpMenu = new BPopUpMenu("version info", true, true);
	item = new BMenuItem("Version Info", NULL);
	item->SetMarked(true);
	popUpMenu->AddItem(item);
	item = new BMenuItem("System Version Info", NULL);
	popUpMenu->AddItem(item);

	menuField = new BMenuField(BRect(0, 0, 100, 15),
		"version kind", NULL, popUpMenu, true);
	menuField->ResizeToPreferred();
	box->SetLabel(menuField);
#endif

	rect.top = 4.0f + ceilf(fontHeight.ascent + fontHeight.descent);
	rect.bottom = rect.top + height;
	fMajorVersionControl = new BTextControl(rect, "major", "Version:", NULL,
		NULL);
	fMajorVersionControl->SetDivider(fMajorVersionControl->StringWidth(
		fMajorVersionControl->Label()) + 4.0f);
	fMajorVersionControl->GetPreferredSize(&width, &height);
	width = 12.0f + fMajorVersionControl->StringWidth("99");
	fMajorVersionControl->ResizeTo(fMajorVersionControl->Divider() + width, height);
	_MakeNumberTextControl(fMajorVersionControl);
	box->AddChild(fMajorVersionControl);

	rect.left = fMajorVersionControl->Frame().right + 1.0f;
	fMiddleVersionControl = new BTextControl(rect, "middle", ".", NULL,
		NULL);
	fMiddleVersionControl->SetDivider(fMiddleVersionControl->StringWidth(
		fMiddleVersionControl->Label()) + 4.0f);
	fMiddleVersionControl->ResizeTo(fMiddleVersionControl->Divider() + width, height);
	_MakeNumberTextControl(fMiddleVersionControl);
	box->AddChild(fMiddleVersionControl);

	rect.left = fMiddleVersionControl->Frame().right + 1.0f;
	fMinorVersionControl = new BTextControl(rect, "middle", ".", NULL,
		NULL);
	fMinorVersionControl->SetDivider(fMinorVersionControl->StringWidth(
		fMinorVersionControl->Label()) + 4.0f);
	fMinorVersionControl->ResizeTo(fMinorVersionControl->Divider() + width, height);
	_MakeNumberTextControl(fMinorVersionControl);
	box->AddChild(fMinorVersionControl);

	fVarietyMenu = new BPopUpMenu("variety", true, true);
	fVarietyMenu->AddItem(new BMenuItem("Development", NULL));
	fVarietyMenu->AddItem(new BMenuItem("Alpha", NULL));
	fVarietyMenu->AddItem(new BMenuItem("Beta", NULL));
	fVarietyMenu->AddItem(new BMenuItem("Gamma", NULL));
	fVarietyMenu->AddItem(item = new BMenuItem("Golden master", NULL));
	item->SetMarked(true);
	fVarietyMenu->AddItem(new BMenuItem("Final", NULL));

	rect.top--;
		// BMenuField oddity
	rect.left = fMinorVersionControl->Frame().right + 6.0f;
	menuField = new BMenuField(rect,
		"variety", NULL, fVarietyMenu, true);
	menuField->ResizeToPreferred();
	box->AddChild(menuField);

	rect.top++;
	rect.left = menuField->Frame().right;
	rect.right = rect.left + 30.0f;	
	fInternalVersionControl = new BTextControl(rect, "internal", "/", NULL,
		NULL);
	fInternalVersionControl->SetDivider(fInternalVersionControl->StringWidth(
		fInternalVersionControl->Label()) + 4.0f);
	fInternalVersionControl->ResizeTo(fInternalVersionControl->Divider() + width, height);
	box->AddChild(fInternalVersionControl);

	rect = box->Bounds().InsetByCopy(8.0f, 0.0f);
	rect.top = fInternalVersionControl->Frame().bottom + 8.0f;
	fShortDescriptionControl = new BTextControl(rect, "short desc", "Short description:",
		NULL, NULL, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
	float labelWidth = fShortDescriptionControl->StringWidth(
		fShortDescriptionControl->Label()) + 4.0f;
	fShortDescriptionControl->SetDivider(labelWidth);
	fShortDescriptionControl->GetPreferredSize(&width, &height);
	fShortDescriptionControl->ResizeTo(rect.Width(), height);

	// TODO: workaround for a GCC 4.1.0 bug? Or is that really what the standard says?
	version_info versionInfo;
	fShortDescriptionControl->TextView()->SetMaxBytes(sizeof(versionInfo.short_info));
	box->AddChild(fShortDescriptionControl);

	rect.OffsetBy(0.0f, fShortDescriptionControl->Bounds().Height() + 5.0f);
	rect.right = rect.left + labelWidth;
	StringView* label = new StringView(rect, NULL, "Long description:", NULL);
	label->SetDivider(labelWidth);
	box->AddChild(label);

	rect.left = rect.right + 3.0f;
	rect.top += 1.0f;
	rect.right = box->Bounds().Width() - 10.0f - B_V_SCROLL_BAR_WIDTH;
	rect.bottom = rect.top + fShortDescriptionControl->Bounds().Height() * 3.0f - 1.0f;
	fLongDescriptionView = new TabFilteringTextView(rect, "long desc",
		rect.OffsetToCopy(B_ORIGIN), B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS
		| B_NAVIGABLE);
	fLongDescriptionView->SetMaxBytes(sizeof(versionInfo.long_info));

	scrollView = new BScrollView("desc scrollview", fLongDescriptionView,
		B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, B_FRAME_EVENTS | B_WILL_DRAW, false, true);
	box->ResizeTo(box->Bounds().Width(), scrollView->Frame().bottom + 8.0f);
	box->AddChild(scrollView);

	// Adjust window size and limits

	width = fInternalVersionControl->Frame().right + 16.0f;
	float minWidth = fBackgroundAppCheckBox->Frame().right + iconBoxWidth + 32.0f;
	if (width > minWidth)
		minWidth = width;

	ResizeTo(Bounds().Width() > minWidth ? Bounds().Width() : minWidth,
		box->Frame().bottom + topView->Frame().top + 8.0f);
	SetSizeLimits(minWidth, 32767.0f, Bounds().Height(), 32767.0f);
	typeBox->SetResizingMode(B_FOLLOW_ALL);
	box->SetResizingMode(B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM);

	fSignatureControl->MakeFocus(true);

	BMimeType::StartWatching(this);
	_SetTo(entry);
}
Beispiel #4
0
void
DocInfoWindow::_SetupDocInfoView(BBox* panel)
{
	BRect bounds(panel->Bounds());
#if HAVE_FULLVERSION_PDF_LIB
	bounds.InsetBy(10.0, 10.0);
#endif

	// add list of keys
	fKeyList = new BMenu("Delete Key");
	BMenuField *menu = new BMenuField(bounds, "delete", "", fKeyList,
		B_FOLLOW_BOTTOM);
	panel->AddChild(menu);
	menu->SetDivider(0);

#ifdef __HAIKU__
	menu->ResizeToPreferred();
	menu->MoveTo(bounds.left, bounds.bottom - menu->Bounds().Height());
#else
	menu->ResizeTo(menu->StringWidth("Delete Key") + 15.0, 25.0);
	menu->MoveTo(bounds.left, bounds.bottom - 25.0);
#endif

	const char* title[6] = { "Title", "Author", "Subject", "Keywords", "Creator",
		NULL };	// PDFlib sets these: "Producer", "CreationDate", not "ModDate"
	BMenu* defaultKeys = new BMenu("Default Keys");
	for (int32 i = 0; title[i] != NULL; ++i)
		defaultKeys->AddItem(new BMenuItem(title[i], new BMessage(DEFAULT_KEY_MSG)));

	BRect frame(menu->Frame());
	menu = new BMenuField(frame, "add", "", defaultKeys, B_FOLLOW_BOTTOM);
	panel->AddChild(menu);
	menu->SetDivider(0);

#ifdef __HAIKU__
	menu->ResizeToPreferred();
	menu->MoveBy(frame.Width() + 10.0, 0.0);
#else
	menu->ResizeTo(menu->StringWidth("Default Keys") + 15.0, 25.0);
	menu->MoveBy(menu->Bounds().Width() + 10.0, 0.0);
#endif

	frame = menu->Frame();
	frame.left = frame.right + 10.0;
	frame.right = bounds.right;
	BTextControl *add = new BTextControl(frame, "add", "Add Key:", "",
		new BMessage(ADD_KEY_MSG), B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM);
	panel->AddChild(add);

	float width, height;
	add->GetPreferredSize(&width, &height);
	add->ResizeTo(bounds.right - frame.left, height);
	add->SetDivider(be_plain_font->StringWidth("Add Key: "));

	bounds.bottom = frame.top - 10.0;
	bounds.right -= B_V_SCROLL_BAR_WIDTH;
	bounds.InsetBy(2.0, 2.0);
	fTable = new BView(bounds, "table", B_FOLLOW_ALL, B_WILL_DRAW);
	fTable->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));

	fTableScrollView = new BScrollView("scroll_table", fTable, B_FOLLOW_ALL, 0,
		false, true);
	panel->AddChild(fTableScrollView);

	BMessage docInfo;
	fDocInfo->FindMessage("doc_info", &docInfo);

	// fill table
	_BuildTable(docInfo);
}
Beispiel #5
0
THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming,
	bool resending, uint32 defaultCharacterSet, int32 defaultAccount)
	:
	BBox(rect, "m_header", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW, B_NO_BORDER),

	fAccountMenu(NULL),
	fEncodingMenu(NULL),
	fAccountID(defaultAccount),
	fAccountTo(NULL),
	fAccount(NULL),
	fBcc(NULL),
	fCc(NULL),
	fSubject(NULL),
	fTo(NULL),
	fDateLabel(NULL),
	fDate(NULL),
	fIncoming(incoming),
	fCharacterSetUserSees(defaultCharacterSet),
	fResending(resending),
	fBccMenu(NULL),
	fCcMenu(NULL),
	fToMenu(NULL),
	fEmailList(NULL)
{
	BMenuField* field;
	BMessage* msg;

	float x = StringWidth( /* The longest title string in the header area */
		B_TRANSLATE("Attachments: ")) + 9;
	float y = TO_FIELD_V;

	BMenuBar* dummy = new BMenuBar(BRect(0, 0, 100, 15), "Dummy");
	AddChild(dummy);
	float width, menuBarHeight;
	dummy->GetPreferredSize(&width, &menuBarHeight);
	dummy->RemoveSelf();
	delete dummy;

	float menuFieldHeight = menuBarHeight + 6;
	float controlHeight = menuBarHeight + floorf(be_plain_font->Size() / 1.15);

	if (!fIncoming) {
		InitEmailCompletion();
		InitGroupCompletion();
	}

	// Prepare the character set selection pop-up menu (we tell the user that
	// it is the Encoding menu, even though it is really the character set).
	// It may appear in the first line, to the right of the From box if the
	// user is reading an e-mail.  It appears on the second line, to the right
	// of the e-mail account menu, if the user is composing a message.  It lets
	// the user quickly select a character set different from the application
	// wide default one, and also shows them which character set is active.  If
	// you are reading a message, you also see an item that says "Automatic"
	// for automatic decoding character set choice.  It can slide around as the
	// window is resized when viewing a message, but not when composing
	// (because the adjacent pop-up menu can't resize dynamically due to a BeOS
	// bug).

	float widestCharacterSet = 0;
	bool markedCharSet = false;
	BMenuItem* item;

	fEncodingMenu = new BPopUpMenu(B_EMPTY_STRING);

	BCharacterSetRoster roster;
	BCharacterSet charset;
	while (roster.GetNextCharacterSet(&charset) == B_OK) {
		BString name(charset.GetPrintName());
		const char* mime = charset.GetMIMEName();
		if (mime)
			name << " (" << mime << ")";

		uint32 convertID;
		if (mime == NULL || strcasecmp(mime, "UTF-8") != 0)
			convertID = charset.GetConversionID();
		else
			convertID = B_MAIL_UTF8_CONVERSION;

		msg = new BMessage(kMsgEncoding);
		msg->AddInt32("charset", convertID);
		fEncodingMenu->AddItem(item = new BMenuItem(name.String(), msg));
		if (convertID == fCharacterSetUserSees && !markedCharSet) {
			item->SetMarked(true);
			markedCharSet = true;
		}
		if (StringWidth(name.String()) > widestCharacterSet)
			widestCharacterSet = StringWidth(name.String());
	}

	msg = new BMessage(kMsgEncoding);
	msg->AddInt32("charset", B_MAIL_US_ASCII_CONVERSION);
	fEncodingMenu->AddItem(item = new BMenuItem("US-ASCII", msg));
	if (fCharacterSetUserSees == B_MAIL_US_ASCII_CONVERSION && !markedCharSet) {
		item->SetMarked(true);
		markedCharSet = true;
	}

	if (!resending && fIncoming) {
		// reading a message, display the Automatic item
		fEncodingMenu->AddSeparatorItem();
		msg = new BMessage(kMsgEncoding);
		msg->AddInt32("charset", B_MAIL_NULL_CONVERSION);
		fEncodingMenu->AddItem(item = new BMenuItem(B_TRANSLATE("Automatic"), msg));
		if (!markedCharSet)
			item->SetMarked(true);
	}

	// First line of the header, From for reading e-mails (includes the
	// character set choice at the right), To when composing (nothing else in
	// the row).

	BRect r;
	char string[20];
	if (fIncoming && !resending) {
		// Set up the character set pop-up menu on the right of "To" box.
		r.Set (windowRect.Width() - widestCharacterSet -
			StringWidth (B_TRANSLATE("Decoding:")) - 2 * SEPARATOR_MARGIN,
				y - 2, windowRect.Width() - SEPARATOR_MARGIN,
				y + menuFieldHeight);
		field = new BMenuField (r, "decoding", B_TRANSLATE("Decoding:"),
			fEncodingMenu, true /* fixedSize */,
			B_FOLLOW_TOP | B_FOLLOW_RIGHT,
			B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP);
		field->SetDivider(field->StringWidth(B_TRANSLATE("Decoding:")) + 5);
		AddChild(field);
		r.Set(SEPARATOR_MARGIN, y,
			  field->Frame().left - SEPARATOR_MARGIN, y + menuFieldHeight);
		sprintf(string, B_TRANSLATE("From:"));
	} else {
		r.Set(x - 12, y, windowRect.Width() - SEPARATOR_MARGIN,
			y + menuFieldHeight);
		string[0] = 0;
	}

	y += controlHeight;
	fTo = new TTextControl(r, string, new BMessage(TO_FIELD), fIncoming,
		resending, B_FOLLOW_LEFT_RIGHT);
	fTo->SetFilter(mail_to_filter);

	if (!fIncoming || resending) {
		fTo->SetChoiceList(&fEmailList);
		fTo->SetAutoComplete(true);
	} else {
		fTo->SetDivider(x - 12 - SEPARATOR_MARGIN);
		fTo->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
	}

	AddChild(fTo);
	msg = new BMessage(FIELD_CHANGED);
	msg->AddInt32("bitmask", FIELD_TO);
	fTo->SetModificationMessage(msg);

	if (!fIncoming || resending) {
		r.right = r.left - 5;
		r.left = r.right - ceilf(be_plain_font->StringWidth(
			B_TRANSLATE("To:")) + 25);
		r.top -= 1;
		fToMenu = new QPopupMenu(B_TRANSLATE("To:"));
		field = new BMenuField(r, "", "", fToMenu, true,
			B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW);
		field->SetDivider(0.0);
		field->SetEnabled(true);
		AddChild(field);
	}

	// "From:" accounts Menu and Encoding Menu.
	if (!fIncoming || resending) {
		// Put the character set box on the right of the From field.
		r.Set(windowRect.Width() - widestCharacterSet -
			StringWidth(B_TRANSLATE("Encoding:")) - 2 * SEPARATOR_MARGIN,
			y - 2, windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight);
		BMenuField* encodingField = new BMenuField(r, "encoding",
			B_TRANSLATE("Encoding:"), fEncodingMenu, true /* fixedSize */,
			B_FOLLOW_TOP | B_FOLLOW_RIGHT,
			B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP);
		encodingField->SetDivider(encodingField->StringWidth(
			B_TRANSLATE("Encoding:")) + 5);
		AddChild(encodingField);

		field = encodingField;

		// And now the "from account" pop-up menu, on the left side, taking the
		// remaining space.

		fAccountMenu = new BPopUpMenu(B_EMPTY_STRING);

		BMailAccounts accounts;
		bool marked = false;
		for (int32 i = 0; i < accounts.CountAccounts(); i++) {
			BMailAccountSettings* account = accounts.AccountAt(i);
			BString name = account->Name();
			name << ":   " << account->RealName() << "  <"
				<< account->ReturnAddress() << ">";

			msg = new BMessage(kMsgFrom);
			BMenuItem *item = new BMenuItem(name, msg);

			msg->AddInt32("id", account->AccountID());

			if (defaultAccount == account->AccountID()) {
				item->SetMarked(true);
				marked = true;
			}
			fAccountMenu->AddItem(item);
		}

		if (!marked) {
			BMenuItem *item = fAccountMenu->ItemAt(0);
			if (item != NULL) {
				item->SetMarked(true);
				fAccountID = item->Message()->FindInt32("id");
			} else {
				fAccountMenu->AddItem(
					item = new BMenuItem(B_TRANSLATE("<none>"), NULL));
				item->SetEnabled(false);
				fAccountID = ~0UL;
			}
			// default account is invalid, set to marked
			// TODO: do this differently, no casting and knowledge
			// of TMailApp here....
			if (TMailApp* app = dynamic_cast<TMailApp*>(be_app))
				app->SetDefaultAccount(fAccountID);
		}

		r.Set(SEPARATOR_MARGIN, y - 2,
			  field->Frame().left - SEPARATOR_MARGIN, y + menuFieldHeight);
		field = new BMenuField(r, "account", B_TRANSLATE("From:"),
			fAccountMenu, true /* fixedSize */,
			B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT,
			B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP);
		AddChild(field, encodingField);
		field->SetDivider(x - 12 - SEPARATOR_MARGIN + kMenuFieldDividerOffset);
		field->SetAlignment(B_ALIGN_RIGHT);
		y += controlHeight;
	} else {
		// To: account
		bool account = BMailAccounts().CountAccounts() > 0;

		r.Set(SEPARATOR_MARGIN, y,
			  windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight);
		if (account)
			r.right -= SEPARATOR_MARGIN + ACCOUNT_FIELD_WIDTH;
		fAccountTo = new TTextControl(r, B_TRANSLATE("To:"), NULL, fIncoming,
			false, B_FOLLOW_LEFT_RIGHT);
		fAccountTo->SetEnabled(false);
		fAccountTo->SetDivider(x - 12 - SEPARATOR_MARGIN);
		fAccountTo->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
		AddChild(fAccountTo);

		if (account) {
			r.left = r.right + 6;  r.right = windowRect.Width() - SEPARATOR_MARGIN;
			fAccount = new TTextControl(r, B_TRANSLATE("Account:"), NULL,
				fIncoming, false, B_FOLLOW_RIGHT | B_FOLLOW_TOP);
			fAccount->SetEnabled(false);
			AddChild(fAccount);
		}
		y += controlHeight;
	}
	
	if (fIncoming) {
		--y;
		r.Set(SEPARATOR_MARGIN, y,
			windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight);
		y += controlHeight;
		fCc = new TTextControl(r, B_TRANSLATE("Cc:"),
			NULL, fIncoming, false, B_FOLLOW_LEFT_RIGHT);
		fCc->SetEnabled(false);
		fCc->SetDivider(x - 12 - SEPARATOR_MARGIN);
		fCc->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
		AddChild(fCc);
	}

	--y;
	r.Set(SEPARATOR_MARGIN, y,
		windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight);
	y += controlHeight;
	fSubject = new TTextControl(r, B_TRANSLATE("Subject:"),
		new BMessage(SUBJECT_FIELD),fIncoming, false, B_FOLLOW_LEFT_RIGHT);
	AddChild(fSubject);
	(msg = new BMessage(FIELD_CHANGED))->AddInt32("bitmask", FIELD_SUBJECT);
	fSubject->SetModificationMessage(msg);
	fSubject->SetDivider(x - 12 - SEPARATOR_MARGIN);
	fSubject->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
	if (fResending)
		fSubject->SetEnabled(false);

	--y;

	if (!fIncoming) {
		r.Set(x - 12, y, CC_FIELD_H + CC_FIELD_WIDTH, y + menuFieldHeight);
		fCc = new TTextControl(r, "", new BMessage(CC_FIELD), fIncoming, false);
		fCc->SetFilter(mail_to_filter);
		fCc->SetChoiceList(&fEmailList);
		fCc->SetAutoComplete(true);
		AddChild(fCc);
		(msg = new BMessage(FIELD_CHANGED))->AddInt32("bitmask", FIELD_CC);
		fCc->SetModificationMessage(msg);

		r.right = r.left - 5;
		r.left = r.right - ceilf(be_plain_font->StringWidth(
			B_TRANSLATE("Cc:")) + 25);
		r.top -= 1;
		fCcMenu = new QPopupMenu(B_TRANSLATE("Cc:"));
		field = new BMenuField(r, "", "", fCcMenu, true,
			B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW);

		field->SetDivider(0.0);
		field->SetEnabled(true);
		AddChild(field);

		r.Set(BCC_FIELD_H + be_plain_font->StringWidth(B_TRANSLATE("Bcc:")), y,
			  windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight);
		y += controlHeight;
		fBcc = new TTextControl(r, "", new BMessage(BCC_FIELD),
						fIncoming, false, B_FOLLOW_LEFT_RIGHT);
		fBcc->SetFilter(mail_to_filter);
		fBcc->SetChoiceList(&fEmailList);
		fBcc->SetAutoComplete(true);
		AddChild(fBcc);
		(msg = new BMessage(FIELD_CHANGED))->AddInt32("bitmask", FIELD_BCC);
		fBcc->SetModificationMessage(msg);

		r.right = r.left - 5;
		r.left = r.right - ceilf(be_plain_font->StringWidth(
			B_TRANSLATE("Bcc:")) + 25);
		r.top -= 1;
		fBccMenu = new QPopupMenu(B_TRANSLATE("Bcc:"));
		field = new BMenuField(r, "", "", fBccMenu, true,
			B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW);
		field->SetDivider(0.0);
		field->SetEnabled(true);
		AddChild(field);
	} else {
		y -= SEPARATOR_MARGIN;
		r.Set(SEPARATOR_MARGIN, y, x - 12 - 1, y + menuFieldHeight);
		fDateLabel = new BStringView(r, "", kDateLabel);
		fDateLabel->SetAlignment(B_ALIGN_RIGHT);
		AddChild(fDateLabel);
		fDateLabel->SetHighColor(0, 0, 0);

		r.Set(r.right + 9, y, windowRect.Width() - SEPARATOR_MARGIN,
			y + menuFieldHeight);
		fDate = new BStringView(r, "", "");
		AddChild(fDate);
		fDate->SetHighColor(0, 0, 0);

		y += controlHeight + 5;
	}
	ResizeTo(Bounds().Width(), y);
}
Beispiel #6
0
RecipeEditor::RecipeEditor(const BRect &frame, const BMessenger &msgr,
						const int32 &number, const char *category)
 :	BWindow(frame,"Add Recipe",B_FLOATING_WINDOW_LOOK, B_MODAL_SUBSET_WINDOW_FEEL,
 			B_ASYNCHRONOUS_CONTROLS),
 	fMessenger(msgr),
 	fNumber(number),
 	fCategory(category)
{
	AddShortcut('W', B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED));
	AddShortcut('Q', B_COMMAND_KEY, new BMessage(M_QUIT_APP));
	
	BView *back = new BView(Bounds(),"back",B_FOLLOW_ALL, B_WILL_DRAW);
	back->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
	AddChild(back);
	
	fCategories = new BMenu("Categories");
	CppSQLite3Query query = DBQuery("select category from categories order by category;",
									"RecipeEditor:get categories");
	while(!query.eof())
	{
		BString cat(DeescapeIllegalCharacters(query.getStringField(0)));
		BMessage *menumsg = new BMessage(M_CATEGORY_CHANGED);
		menumsg->AddString("name",cat);
		fCategories->AddItem(new BMenuItem(cat.String(),menumsg));
		query.nextRow();
	}
	fCategories->SetRadioMode(true);
	fCategories->SetLabelFromMarked(true);
	if(fCategories->CountItems()>0)
		fCategories->ItemAt(0)->SetMarked(true);
	BRect r(10,10,10 + fCategories->MaxContentWidth(),11);
	BMenuField *field = new BMenuField(r,"field","Category",fCategories,
										B_FOLLOW_LEFT | B_FOLLOW_TOP,
										B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP);
	back->AddChild(field);
	field->ResizeToPreferred();
	r = field->Frame();
	
	if(category)
	{
		BMenuItem *marked = fCategories->FindItem(category);
		if(marked)
			marked->SetMarked(true);
	}
	else
	{
		BMenuItem *marked = fCategories->ItemAt(0L);
		if(marked)
			marked->SetMarked(true);
	}
	
	r.OffsetBy(0,r.Height() + 10);
	fNameBox = new AutoTextControl(r,"namebox","Name: ",NULL,NULL,
									B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
									B_WILL_DRAW | B_PULSE_NEEDED | B_NAVIGABLE |
									B_NAVIGABLE_JUMP);
	fNameBox->SetEscapeCancel(true);
	fNameBox->SetDivider(be_plain_font->StringWidth("Name ") + 5);
	back->AddChild(fNameBox);
	fNameBox->ResizeToPreferred();
	r = fNameBox->Frame();
	r.right = Bounds().right - 10;
	fNameBox->ResizeTo(r.Width(), r.Height());
	
	r.OffsetBy(0,r.Height() + 10);
	BStringView *label = new BStringView(r,"inglabel","Ingredients:");
	back->AddChild(label);
	
	r.OffsetBy(0,r.Height() + 10);
	r.bottom = r.top + 100;
	r.right -= B_V_SCROLL_BAR_WIDTH;
	
	BRect textrect = r.OffsetToCopy(0,0);
	textrect.InsetBy(10,10);
	fIngredientBox = new BTextView(r, "ingredients", textrect, B_FOLLOW_ALL,
									B_WILL_DRAW | B_PULSE_NEEDED | B_NAVIGABLE |
									B_NAVIGABLE_JUMP);
	fIngredientBox->SetDoesUndo(true);
	
	
	BScrollView *ingredscroll = new BScrollView("ingredients_scroller",fIngredientBox,
										B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,0,false, true);
	back->AddChild(ingredscroll);
	
	r = ingredscroll->Frame();
	
	label = new BStringView(BRect(10,10,11,11),"dirlabel","Directions:");
	label->ResizeToPreferred();
	label->MoveTo(10, r.bottom + 10);
	back->AddChild(label);
	
	r.OffsetBy(0,r.Height() + 20 + label->Frame().Height());
	r.right -= B_V_SCROLL_BAR_WIDTH;
	textrect = r.OffsetToCopy(0,0);
	textrect.InsetBy(10,10);
	fDirectionsBox = new BTextView(r, "directions", textrect, B_FOLLOW_ALL,
									B_WILL_DRAW | B_PULSE_NEEDED | B_NAVIGABLE |
									B_NAVIGABLE_JUMP);
	fDirectionsBox->SetDoesUndo(true);
	
	BScrollView *dirscroll = new BScrollView("directions_scroller",fDirectionsBox,
										B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,0,false, true);
	back->AddChild(dirscroll);
	
	
	fOK = new BButton(BRect(10,10,11,11),"ok","Cancel", new BMessage(M_ADD_RECIPE),
							B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM, B_WILL_DRAW);
	fOK->ResizeToPreferred();
	fOK->SetLabel("OK");
	fOK->MoveTo(Bounds().right - fOK->Bounds().Width() - 10,
				Bounds().bottom - fOK->Bounds().Height() - 10);
	r = fOK->Frame();
	back->AddChild(fOK);
	
	r.OffsetBy(-r.Width() - 10, 0);
	fCancel = new BButton(r,"cancel","Cancel",new BMessage(B_QUIT_REQUESTED),
						B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM, B_WILL_DRAW);
	back->AddChild(fCancel);
	
	field->MakeFocus(true);
	
	ResizeTo(Bounds().Width(),
			fDirectionsBox->Parent()->Frame().bottom + 20 + fOK->Bounds().Height());
	
	dirscroll->SetResizingMode(B_FOLLOW_ALL);
	
	// This is the part that's different for editing a recipe as opposed to
	// just adding one to the database
	if(number >= 0 && category)
	{
		SetTitle("Edit Recipe");
		BString name, ingredients, directions;
		if(GetRecipe(number,category,name,ingredients,directions))
		{
			BMenuItem *item = fCategories->FindItem(category);
			if(item)
				item->SetMarked(true);
			
			fNameBox->SetText(name.String());
			fIngredientBox->SetText(ingredients.String());
			fDirectionsBox->SetText(directions.String());
			fOK->SetMessage(new BMessage(M_EDIT_RECIPE));
		}
	}
	
	AddShortcut(B_ENTER, B_COMMAND_KEY, new BMessage(fOK->Command()));
}
Beispiel #7
0
CatBrowser::CatBrowser(const BRect &frame, const BMessenger &msgr,
						const char *category, bool editmode)
 :	BWindow(frame,"Recipe Browser",B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS),
 	fMessenger(msgr),
 	fCategoryCount(-1),
 	fCurrentPage(-1),
 	fEditMode(editmode)
{
	AddShortcut('W', B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED));
	AddShortcut('Q', B_COMMAND_KEY, new BMessage(M_QUIT_APP));
	
	BView *back = new BView(Bounds(),"back",B_FOLLOW_ALL, B_WILL_DRAW);
	back->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
	AddChild(back);
	
	fCategories = new BMenu("Categories");
	CppSQLite3Query query = DBQuery("select category from categories order by category;",
									"FindWindow:get categories");
	while(!query.eof())
	{
		BString cat(DeescapeIllegalCharacters(query.getStringField(0)));
		fCategories->AddItem(new BMenuItem(cat.String(),new BMessage(M_SET_CATEGORY)));
		query.nextRow();
	}
	fCategories->SetRadioMode(true);
	fCategories->SetLabelFromMarked(true);
	if(fCategories->CountItems()>0)
		fCategories->ItemAt(0)->SetMarked(true);
	BRect r(10,10,10 + fCategories->MaxContentWidth(),11);
	BMenuField *field = new BMenuField(r,"field","Category",fCategories);
	back->AddChild(field);
	field->ResizeToPreferred();
	r = field->Frame();
	
	BMenuItem *marked = fCategories->FindItem(category);
	if(marked)
		marked->SetMarked(true);
	
	r.OffsetBy(0,r.Height() + 10);
	r.right = Bounds().right - 10 - B_V_SCROLL_BAR_WIDTH;
	r.bottom = Bounds().bottom - 10;
	
	fList = new BListView(r, "newlist", B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL);
	fList->SetInvocationMessage(new BMessage(M_SET_RECIPE));
	BScrollView *newscroll = new BScrollView("newscroll",fList,
											B_FOLLOW_ALL, 0, false, true);
	back->AddChild(newscroll);
	
	fBack = new BButton(BRect(10,10,11,11),"back","Back", new BMessage(M_RESULTS_BACK),
					B_FOLLOW_LEFT | B_FOLLOW_BOTTOM, B_WILL_DRAW);
	fBack->ResizeToPreferred();
	fBack->ResizeTo(be_plain_font->StringWidth("Back") + 15,fBack->Frame().Height());
	fBack->MoveTo(10,Bounds().bottom - fBack->Bounds().Height() - 10);
	r = fBack->Frame();
	back->AddChild(fBack);
	fBack->SetEnabled(false);
	
	r.OffsetBy(r.Width() + 5, 0);
	fNext = new BButton(r,"next","Next", new BMessage(M_RESULTS_NEXT),
					B_FOLLOW_LEFT | B_FOLLOW_BOTTOM, B_WILL_DRAW);
	back->AddChild(fNext);
	fNext->SetEnabled(false);
	
	fClose = new BButton(BRect(10,10,11,11),"close","View Recipe", new BMessage(B_QUIT_REQUESTED),
					B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM, B_WILL_DRAW);
	fClose->ResizeToPreferred();
	fClose->SetLabel("Close");
	fClose->MoveTo(Bounds().right - fClose->Bounds().Width() - 10,r.top);
	r = fClose->Frame();
	fClose->MakeDefault(true);
	
	r.OffsetBy(-r.Width() - 10, 0);
	fOpen = new BButton(r,"openrecipe","View Recipe",new BMessage(M_SET_RECIPE),
						B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM, B_WILL_DRAW);
	
	back->AddChild(fOpen);
	back->AddChild(fClose);
	
	fList->MakeFocus(true);
	
	r = fList->Parent()->Frame();
	r.bottom = fClose->Frame().top - 10;
	fList->Parent()->ResizeTo(r.Width(),r.Height());
	
	float controlwidth = (fBack->Frame().Width() * 2) + (fOpen->Frame().Width() * 2) + 65;
	if( Frame().Width() < controlwidth )
		ResizeTo(controlwidth, Frame().Height());
	
	if(fEditMode)
	{
		// This hidden mode (Command-Click on the browser menu item) is for doing
		// massive edits on the database
		fList->SetListType(B_MULTIPLE_SELECTION_LIST);
		fList->SetSelectionMessage(new BMessage(M_SET_RECIPE));
		
		BMenu *editmenu = new BMenu("Edit");
		editmenu->AddItem(new BMenuItem("Mass Recategorize",new BMessage(M_SHOW_RECAT)));
		editmenu->AddItem(new BMenuItem("Delete Recipe",new BMessage(M_DELETE_RECIPE)));
		
		r.Set(10,10,10 + be_plain_font->StringWidth("Edit") + 25,11);
		r.OffsetTo(Bounds().right - 10 - r.Width(), 10);
		BMenuField *editfield = new BMenuField(r,"editfield","Edit",editmenu,
											B_FOLLOW_RIGHT | B_FOLLOW_TOP);
		editfield->SetDivider(0);
		back->AddChild(editfield);
		
		fSortString = " order by number ";
	}
	
	PostMessage(M_SET_CATEGORY);
}