예제 #1
0
void
BreakpointEditWindow::_Init()
{
	fConditionInput = new BTextControl(NULL, NULL, NULL);
	BLayoutItem* textLayoutItem = fConditionInput->CreateTextViewLayoutItem();
	textLayoutItem->SetExplicitMinSize(BSize(200.0, B_SIZE_UNSET));
	BLayoutBuilder::Group<>(this, B_VERTICAL)
		.SetInsets(B_USE_DEFAULT_SPACING)
		.Add((fAlwaysRadio = new BRadioButton("Break always",
				new BMessage(MSG_SET_BREAK_ALWAYS))))
		.AddGroup(B_HORIZONTAL)
			.Add((fConditionRadio = new BRadioButton("Break on condition: ",
				new BMessage(MSG_SET_BREAK_ON_CONDITION))))
			.Add(textLayoutItem)
		.End()
		.AddGroup(B_HORIZONTAL)
			.AddGlue()
			.Add((fSaveButton = new BButton("Save",
				new BMessage(MSG_SAVE_BREAKPOINT_SETTINGS))))
			.Add((fCancelButton = new BButton("Cancel",
				new BMessage(B_CANCEL))))
		.End()
	.End();

	AutoLocker< ::Team> teamLocker(fTeam);
	if (fTargetBreakpoint->HasCondition()) {
		fConditionRadio->SetValue(B_CONTROL_ON);
		fConditionInput->SetText(fTargetBreakpoint->Condition());
	} else {
		fAlwaysRadio->SetValue(B_CONTROL_ON);
		fConditionInput->SetEnabled(false);
	}
}
예제 #2
0
void
ExpressionPromptWindow::_Init()
{
	fExpressionInput = new BTextControl("Expression:", NULL, NULL);
	BLayoutItem* labelItem = fExpressionInput->CreateLabelLayoutItem();
	BLayoutItem* inputItem = fExpressionInput->CreateTextViewLayoutItem();
	inputItem->SetExplicitMinSize(BSize(200.0, B_SIZE_UNSET));
	inputItem->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
	labelItem->View()->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);

	BLayoutBuilder::Group<>(this, B_VERTICAL)
		.SetInsets(B_USE_DEFAULT_SPACING)
		.AddGroup(B_HORIZONTAL, 4.0f)
			.Add(labelItem)
			.Add(inputItem)
		.End()
		.AddGroup(B_HORIZONTAL, 4.0f)
			.AddGlue()
			.Add((fCancelButton = new BButton("Cancel",
					new BMessage(B_QUIT_REQUESTED))))
			.Add((fAddButton = new BButton("Add",
					new BMessage(MSG_ADD_NEW_EXPRESSION))))
		.End();

	fExpressionInput->SetTarget(this);
	fCancelButton->SetTarget(this);
	fAddButton->SetTarget(this);
	fAddButton->MakeDefault(true);
	fExpressionInput->TextView()->MakeFocus(true);
}
예제 #3
0
파일: NamePanel.cpp 프로젝트: DonCN/haiku
NamePanel::NamePanel(const char* label, const char* text, BWindow* window,
		BHandler* target, BMessage* message, const BSize& size)
	:
	Panel(BRect(B_ORIGIN, size), B_TRANSLATE("Name Panel"),
		B_MODAL_WINDOW_LOOK, B_MODAL_SUBSET_WINDOW_FEEL,
		B_ASYNCHRONOUS_CONTROLS | B_NOT_V_RESIZABLE
			| B_AUTO_UPDATE_SIZE_LIMITS),
	fWindow(window),
	fTarget(target),
	fMessage(message)
{
	BButton* defaultButton = new BButton(B_TRANSLATE("OK"),
		new BMessage(MSG_PANEL_OK));
	BButton* cancelButton = new BButton(B_TRANSLATE("Cancel"),
		new BMessage(MSG_PANEL_CANCEL));
	fNameTC = new BTextControl(label, text, NULL);
	BLayoutItem* inputItem = fNameTC->CreateTextViewLayoutItem();
	inputItem->SetExplicitMinSize(
		BSize(fNameTC->StringWidth("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"),
			B_SIZE_UNSET));

	BLayoutBuilder::Group<>(this, B_VERTICAL, 10)
		.AddGlue()

		// controls
		.AddGroup(B_HORIZONTAL, 5)
			.AddStrut(5)

			// text control
			.Add(fNameTC->CreateLabelLayoutItem())
			.Add(inputItem)
			.AddStrut(5)
			.End()

		.AddGlue()

		// buttons
		.AddGroup(B_HORIZONTAL, 5)
			.AddGlue()
			.Add(cancelButton)
			.Add(defaultButton)
			.AddStrut(5)
			.End()

		.AddGlue();

	SetDefaultButton(defaultButton);
	fNameTC->MakeFocus(true);

	if (fWindow && fWindow->Lock()) {
		fSavedTargetWindowFeel = fWindow->Feel();
		if (fSavedTargetWindowFeel != B_NORMAL_WINDOW_FEEL)
			fWindow->SetFeel(B_NORMAL_WINDOW_FEEL);
		fWindow->Unlock();
	}	

	AddToSubset(fWindow);
}
예제 #4
0
void
TFilePanel::RestoreState()
{
	BNode defaultingNode;
	if (DefaultStateSourceNode(kDefaultFilePanelTemplate, &defaultingNode,
			false)) {
		AttributeStreamFileNode streamNodeSource(&defaultingNode);
		RestoreWindowState(&streamNodeSource);
		PoseView()->Init(&streamNodeSource);
	} else {
		RestoreWindowState(NULL);
		PoseView()->Init(NULL);
	}

	// Finish UI creation now that the PoseView is initialized
	BLayoutItem* item
		= fBorderedView->GroupLayout()->AddView(0, fPoseView->TitleView());
	BSize minSize = item->MinSize();
	BSize maxSize = item->MaxSize();
	item->SetExplicitMinSize(BSize(minSize.Width(), kTitleViewHeight));
	item->SetExplicitMaxSize(BSize(maxSize.Width(), kTitleViewHeight));

	BRect rect(fBorderedView->Frame());
	rect.right = rect.left + kCountViewWidth;
	rect.top = rect.bottom + 1;
	rect.bottom = rect.top + PoseView()->HScrollBar()->Bounds().Height() - 1;
	PoseView()->CountView()->MoveTo(rect.LeftTop());
	PoseView()->CountView()->ResizeTo(rect.Size());
	PoseView()->CountView()->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
	fBackView->AddChild(PoseView()->CountView(), fBorderedView);

	PoseView()->HScrollBar()->MoveBy(kCountViewWidth + 1, 0);
	PoseView()->HScrollBar()->ResizeBy(-kCountViewWidth - 1, 0);

	// The Be Book states that the BTitleView will have a name of "TitleView",
	// and so some apps will try to grab it by that name and move it around.
	// They don't need to, because resizing "PoseView" (really the BorderedView)
	// will resize the BTitleView as well. So just create a dummy view here
	// so that they don't get NULL when trying to find the view.
	BView* dummyTitleView = new BView(BRect(), "TitleView", B_FOLLOW_NONE, 0);
	fBackView->AddChild(dummyTitleView);
	dummyTitleView->Hide();
}
예제 #5
0
void
PackageView::_InitView()
{
	SetViewUIColor(B_PANEL_BACKGROUND_COLOR);

	float fontHeight = be_plain_font->Size();
	rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);

	BTextView* packageDescriptionView = new DescriptionTextView(
		"package description", fontHeight * 13);
	packageDescriptionView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
	packageDescriptionView->SetText(fInfo.GetDescription());
	packageDescriptionView->MakeEditable(false);
	packageDescriptionView->MakeSelectable(false);
	packageDescriptionView->SetFontAndColor(be_plain_font, B_FONT_ALL,
		&textColor);

	BScrollView* descriptionScrollView = new BScrollView(
		"package description scroll view", packageDescriptionView,
		0, false, true, B_NO_BORDER);

	// Install type menu field
	fInstallTypes = new BPopUpMenu(B_TRANSLATE("none"));
	BMenuField* installType = new BMenuField("install_type",
		B_TRANSLATE("Installation type:"), fInstallTypes);

	// Install type description text view
	fInstallTypeDescriptionView = new DescriptionTextView(
		"install type description", fontHeight * 4);
	fInstallTypeDescriptionView->MakeEditable(false);
	fInstallTypeDescriptionView->MakeSelectable(false);
	fInstallTypeDescriptionView->SetInsets(8, 0, 0, 0);
		// Left inset needs to match BMenuField text offset
	fInstallTypeDescriptionView->SetText(
		B_TRANSLATE("No installation type selected"));
	fInstallTypeDescriptionView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
	BFont font(be_plain_font);
	font.SetSize(ceilf(font.Size() * 0.85));
	fInstallTypeDescriptionView->SetFontAndColor(&font, B_FONT_ALL,
		&textColor);

	BScrollView* installTypeScrollView = new BScrollView(
		"install type description scroll view", fInstallTypeDescriptionView,
		 0, false, true, B_NO_BORDER);

	// Destination menu field
	fDestination = new BPopUpMenu(B_TRANSLATE("none"));
	fDestField = new BMenuField("install_to", B_TRANSLATE("Install to:"),
		fDestination);

	fBeginButton = new BButton("begin_button", B_TRANSLATE("Begin"),
		new BMessage(P_MSG_INSTALL));

	BLayoutItem* typeLabelItem = installType->CreateLabelLayoutItem();
	BLayoutItem* typeMenuItem = installType->CreateMenuBarLayoutItem();

	BLayoutItem* destFieldLabelItem = fDestField->CreateLabelLayoutItem();
	BLayoutItem* destFieldMenuItem = fDestField->CreateMenuBarLayoutItem();

	float forcedMinWidth = be_plain_font->StringWidth("XXX") * 5;
	destFieldMenuItem->SetExplicitMinSize(BSize(forcedMinWidth, B_SIZE_UNSET));
	typeMenuItem->SetExplicitMinSize(BSize(forcedMinWidth, B_SIZE_UNSET));

	BAlignment labelAlignment(B_ALIGN_RIGHT, B_ALIGN_VERTICAL_UNSET);
	typeLabelItem->SetExplicitAlignment(labelAlignment);
	destFieldLabelItem->SetExplicitAlignment(labelAlignment);

	// Build the layout
	BLayoutBuilder::Group<>(this, B_VERTICAL)
		.Add(descriptionScrollView)
		.AddGrid(B_USE_SMALL_SPACING, B_USE_DEFAULT_SPACING)
			.Add(typeLabelItem, 0, 0)
			.Add(typeMenuItem, 1, 0)
			.Add(installTypeScrollView, 1, 1)
			.Add(destFieldLabelItem, 0, 2)
			.Add(destFieldMenuItem, 1, 2)
		.End()
		.AddGroup(B_HORIZONTAL)
			.AddGlue()
			.Add(fBeginButton)
		.End()
		.SetInsets(B_USE_DEFAULT_SPACING)
	;

	fBeginButton->MakeDefault(true);
}
예제 #6
0
	KeyRequestView()
		:
		BView("KeyRequestView", B_WILL_DRAW),
		fPassword(NULL)
	{
		SetViewUIColor(B_PANEL_BACKGROUND_COLOR);

		BGroupLayout* rootLayout = new(std::nothrow) BGroupLayout(B_VERTICAL);
		if (rootLayout == NULL)
			return;

		SetLayout(rootLayout);

		BGridView* controls = new(std::nothrow) BGridView();
		if (controls == NULL)
			return;

		BGridLayout* layout = controls->GridLayout();

		float inset = ceilf(be_plain_font->Size() * 0.7);
		rootLayout->SetInsets(inset, inset, inset, inset);
		rootLayout->SetSpacing(inset);
		layout->SetSpacing(inset, inset);

		BStringView* label = new(std::nothrow) BStringView("keyringLabel",
			B_TRANSLATE("Keyring:"));
		if (label == NULL)
			return;

		int32 row = 0;
		layout->AddView(label, 0, row);

		fKeyringName = new(std::nothrow) BStringView("keyringName", "");
		if (fKeyringName == NULL)
			return;

		layout->AddView(fKeyringName, 1, row++);

		fPassword = new(std::nothrow) BTextControl(B_TRANSLATE("Password:"******"", NULL);
		if (fPassword == NULL)
			return;

		BLayoutItem* layoutItem = fPassword->CreateTextViewLayoutItem();
		layoutItem->SetExplicitMinSize(BSize(fPassword->StringWidth(
				"0123456789012345678901234567890123456789") + inset,
			B_SIZE_UNSET));

		layout->AddItem(fPassword->CreateLabelLayoutItem(), 0, row);
		layout->AddItem(layoutItem, 1, row++);

		BGroupView* buttons = new(std::nothrow) BGroupView(B_HORIZONTAL);
		if (buttons == NULL)
			return;

		fCancelButton = new(std::nothrow) BButton(B_TRANSLATE("Cancel"),
			new BMessage(kMessageCancel));
		buttons->GroupLayout()->AddView(fCancelButton);

		buttons->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue());

		fUnlockButton = new(std::nothrow) BButton(B_TRANSLATE("Unlock"),
			new BMessage(kMessageUnlock));
		buttons->GroupLayout()->AddView(fUnlockButton);

		BTextView* message = new(std::nothrow) BTextView("message");
		message->SetText(B_TRANSLATE("An application wants to access the "
			"keyring below, but it is locked with a passphrase. Please enter "
			"the passphrase to unlock the keyring.\n"
			"If you unlock the keyring, it stays unlocked until the system is "
			"shut down or the keyring is manually locked again.\n"
			"If you cancel this dialog the keyring will remain locked."));
		message->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
		rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
		message->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor);
		message->MakeEditable(false);
		message->MakeSelectable(false);
		message->SetWordWrap(true);

		rootLayout->AddView(message);
		rootLayout->AddView(controls);
		rootLayout->AddView(buttons);
	}
예제 #7
0
EthernetSettingsView::EthernetSettingsView()
    :
    BView("EthernetSettingsView", 0, NULL),
    fCurrentSettings(NULL)
{
    SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));

    fSocket = socket(AF_INET, SOCK_DGRAM, 0);
    _GatherInterfaces();

    // build the GUI
    BGroupLayout* rootLayout = new BGroupLayout(B_VERTICAL);
    SetLayout(rootLayout);

    BGridView* controlsGroup = new BGridView();
    BGridLayout* layout = controlsGroup->GridLayout();

    // insets
    float inset = ceilf(be_plain_font->Size() * 0.7);
    rootLayout->SetInsets(inset, inset, inset, inset);
    rootLayout->SetSpacing(inset);
    layout->SetSpacing(inset, inset);

    BPopUpMenu* deviceMenu = new BPopUpMenu(B_TRANSLATE("<no adapter>"));
    for (int32 i = 0; i < fInterfaces.CountItems(); i++) {
        BString& name = *fInterfaces.ItemAt(i);
        BString label = name;
        BMessage* info = new BMessage(kMsgInfo);
        info->AddString("interface", name.String());
        BMenuItem* item = new BMenuItem(label.String(), info);
        deviceMenu->AddItem(item);
    }

    BPopUpMenu* modeMenu = new BPopUpMenu("modes");
    modeMenu->AddItem(new BMenuItem(B_TRANSLATE("Static"),
                                    new BMessage(kMsgStaticMode)));
    modeMenu->AddItem(new BMenuItem(B_TRANSLATE("DHCP"),
                                    new BMessage(kMsgDHCPMode)));
    modeMenu->AddSeparatorItem();
    modeMenu->AddItem(new BMenuItem(B_TRANSLATE("Disabled"),
                                    new BMessage(kMsgDisabledMode)));

    BPopUpMenu* networkMenu = new BPopUpMenu("networks");

    fDeviceMenuField = new BMenuField(B_TRANSLATE("Adapter:"), deviceMenu);
    layout->AddItem(fDeviceMenuField->CreateLabelLayoutItem(), 0, 0);
    layout->AddItem(fDeviceMenuField->CreateMenuBarLayoutItem(), 1, 0);

    fNetworkMenuField = new BMenuField(B_TRANSLATE("Network:"), networkMenu);
    layout->AddItem(fNetworkMenuField->CreateLabelLayoutItem(), 0, 1);
    layout->AddItem(fNetworkMenuField->CreateMenuBarLayoutItem(), 1, 1);

    fTypeMenuField = new BMenuField(B_TRANSLATE("Mode:"), modeMenu);
    layout->AddItem(fTypeMenuField->CreateLabelLayoutItem(), 0, 2);
    layout->AddItem(fTypeMenuField->CreateMenuBarLayoutItem(), 1, 2);

    fIPTextControl = new BTextControl(B_TRANSLATE("IP address:"), "", NULL);
    SetupTextControl(fIPTextControl);

    BLayoutItem* layoutItem = fIPTextControl->CreateTextViewLayoutItem();
    layoutItem->SetExplicitMinSize(BSize(
                                       fIPTextControl->StringWidth("XXX.XXX.XXX.XXX") + inset,
                                       B_SIZE_UNSET));

    layout->AddItem(fIPTextControl->CreateLabelLayoutItem(), 0, 3);
    layout->AddItem(layoutItem, 1, 3);

    fNetMaskTextControl = new BTextControl(B_TRANSLATE("Netmask:"), "", NULL);
    SetupTextControl(fNetMaskTextControl);
    layout->AddItem(fNetMaskTextControl->CreateLabelLayoutItem(), 0, 4);
    layout->AddItem(fNetMaskTextControl->CreateTextViewLayoutItem(), 1, 4);

    fGatewayTextControl = new BTextControl(B_TRANSLATE("Gateway:"), "", NULL);
    SetupTextControl(fGatewayTextControl);
    layout->AddItem(fGatewayTextControl->CreateLabelLayoutItem(), 0, 5);
    layout->AddItem(fGatewayTextControl->CreateTextViewLayoutItem(), 1, 5);

    // TODO: Replace the DNS text controls by a BListView with add/remove
    // functionality and so on...
    fPrimaryDNSTextControl = new BTextControl(B_TRANSLATE("DNS #1:"), "",
            NULL);
    SetupTextControl(fPrimaryDNSTextControl);
    layout->AddItem(fPrimaryDNSTextControl->CreateLabelLayoutItem(), 0, 6);
    layout->AddItem(fPrimaryDNSTextControl->CreateTextViewLayoutItem(), 1, 6);

    fSecondaryDNSTextControl = new BTextControl(B_TRANSLATE("DNS #2:"), "",
            NULL);
    SetupTextControl(fSecondaryDNSTextControl);
    layout->AddItem(fSecondaryDNSTextControl->CreateLabelLayoutItem(), 0, 7);
    layout->AddItem(fSecondaryDNSTextControl->CreateTextViewLayoutItem(), 1, 7);

    fDomainTextControl = new BTextControl(B_TRANSLATE("Domain:"), "", NULL);
    SetupTextControl(fDomainTextControl);
    layout->AddItem(fDomainTextControl->CreateLabelLayoutItem(), 0, 8);
    layout->AddItem(fDomainTextControl->CreateTextViewLayoutItem(), 1, 8);

    fErrorMessage = new BStringView("error", "");
    fErrorMessage->SetAlignment(B_ALIGN_LEFT);
    fErrorMessage->SetFont(be_bold_font);
    fErrorMessage->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));

    layout->AddView(fErrorMessage, 1, 9);

    // button group (TODO: move to window, but take care of
    // enabling/disabling)
    BGroupView* buttonGroup = new BGroupView(B_HORIZONTAL);

    fRevertButton = new BButton(B_TRANSLATE("Revert"),
                                new BMessage(kMsgRevert));
    fRevertButton->SetEnabled(false);
    buttonGroup->GroupLayout()->AddView(fRevertButton);

    buttonGroup->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue());

    fApplyButton = new BButton(B_TRANSLATE("Apply"), new BMessage(kMsgApply));
    fApplyButton->SetEnabled(false);
    buttonGroup->GroupLayout()->AddView(fApplyButton);

    rootLayout->AddView(controlsGroup);
    rootLayout->AddView(buttonGroup);
}
예제 #8
0
ModifierKeysWindow::ModifierKeysWindow()
	:
	BWindow(BRect(0, 0, 360, 220), B_TRANSLATE("Modifier keys"),
		B_FLOATING_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE
			| B_AUTO_UPDATE_SIZE_LIMITS)
{
	get_key_map(&fCurrentMap, &fCurrentBuffer);
	get_key_map(&fSavedMap, &fSavedBuffer);

	BStringView* keyRole = new BStringView("key role",
		B_TRANSLATE_COMMENT("Role", "As in the role of a modifier key"));
	keyRole->SetAlignment(B_ALIGN_RIGHT);
	keyRole->SetFont(be_bold_font);

	BStringView* keyLabel = new BStringView("key label",
		B_TRANSLATE_COMMENT("Key", "As in a computer keyboard key"));
	keyLabel->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
	keyLabel->SetFont(be_bold_font);

	BMenuField* shiftMenuField = _CreateShiftMenuField();
	shiftMenuField->SetAlignment(B_ALIGN_RIGHT);

	BMenuField* controlMenuField = _CreateControlMenuField();
	controlMenuField->SetAlignment(B_ALIGN_RIGHT);

	BMenuField* optionMenuField = _CreateOptionMenuField();
	optionMenuField->SetAlignment(B_ALIGN_RIGHT);

	BMenuField* commandMenuField = _CreateCommandMenuField();
	commandMenuField->SetAlignment(B_ALIGN_RIGHT);

	fShiftConflictView = new ConflictView("shift warning view");
	fShiftConflictView->SetExplicitMaxSize(BSize(15, 15));

	fControlConflictView = new ConflictView("control warning view");
	fControlConflictView->SetExplicitMaxSize(BSize(15, 15));

	fOptionConflictView = new ConflictView("option warning view");
	fOptionConflictView->SetExplicitMaxSize(BSize(15, 15));

	fCommandConflictView = new ConflictView("command warning view");
	fCommandConflictView->SetExplicitMaxSize(BSize(15, 15));

	fCancelButton = new BButton("cancelButton", B_TRANSLATE("Cancel"),
		new BMessage(B_QUIT_REQUESTED));

	fRevertButton = new BButton("revertButton", B_TRANSLATE("Revert"),
		new BMessage(kMsgRevertModifiers));
	fRevertButton->SetEnabled(false);

	fOkButton = new BButton("okButton", B_TRANSLATE("Set modifier keys"),
		new BMessage(kMsgApplyModifiers));
	fOkButton->MakeDefault(true);

	// Build the layout
	SetLayout(new BGroupLayout(B_VERTICAL));

	float forcedMinWidth = be_plain_font->StringWidth("XXX") * 4;
	keyRole->SetExplicitMinSize(BSize(forcedMinWidth, B_SIZE_UNSET));

	BLayoutItem* shiftLabel = shiftMenuField->CreateLabelLayoutItem();
	shiftLabel->SetExplicitMinSize(BSize(forcedMinWidth, B_SIZE_UNSET));
	BLayoutItem* controlLabel = controlMenuField->CreateLabelLayoutItem();
	controlLabel->SetExplicitMinSize(BSize(forcedMinWidth, B_SIZE_UNSET));
	BLayoutItem* optionLabel = optionMenuField->CreateLabelLayoutItem();
	optionLabel->SetExplicitMinSize(BSize(forcedMinWidth, B_SIZE_UNSET));
	BLayoutItem* commandLabel = commandMenuField->CreateLabelLayoutItem();
	commandLabel->SetExplicitMinSize(BSize(forcedMinWidth, B_SIZE_UNSET));

	AddChild(BLayoutBuilder::Group<>(B_VERTICAL, B_USE_SMALL_SPACING)
		.AddGroup(B_HORIZONTAL)
			.Add(keyRole)
			.Add(keyLabel)
			.End()
		.AddGroup(B_HORIZONTAL)
			.Add(shiftLabel)
			.Add(shiftMenuField->CreateMenuBarLayoutItem())
			.Add(fShiftConflictView)
			.End()
		.AddGroup(B_HORIZONTAL)
			.Add(controlLabel)
			.Add(controlMenuField->CreateMenuBarLayoutItem())
			.Add(fControlConflictView)
			.End()
		.AddGroup(B_HORIZONTAL)
			.Add(optionLabel)
			.Add(optionMenuField->CreateMenuBarLayoutItem())
			.Add(fOptionConflictView)
			.End()
		.AddGroup(B_HORIZONTAL)
			.Add(commandLabel)
			.Add(commandMenuField->CreateMenuBarLayoutItem())
			.Add(fCommandConflictView)
			.End()
		.AddGlue()
		.AddGroup(B_HORIZONTAL)
			.Add(fCancelButton)
			.AddGlue()
			.Add(fRevertButton)
			.Add(fOkButton)
			.End()
		.SetInsets(B_USE_DEFAULT_SPACING)
	);

	_MarkMenuItems();
	_ValidateDuplicateKeys();

	PostMessage(kMsgHideShowIcons);
}
/*!	\brief		Constructor for the ActivityWindow class.
 *		\param[in]	data			The data to be displayed.
 *		\param[in]	target		The process to be notified about user's choise.
 *		\param[in]	name			Name of the Event.
 *		\param[in]	category		Category of the Event.
 *		\param[in]	templateMessage		The message to be sent to the target.
 *										If \c NULL is passed, then a new message is constructed
 *										with \c kActivityWindowRepsonceMessage value in \c what.
 *		\param[in]	reminder		\c true if the window is constructed for a reminder, else
 *										\c false. Actually, it matters only for explanation to user.
 *										Default is \c false (it's not a reminder).
 *		\note			A note on memory management:
 *						\c data (the ActionData) belongs to the caller, but it's used only for
 *						initialization of this window. I. e., if the user makes changes to the
 *						data while an ActivityWindow is open, the changes won't be reflected.
 *						However, \c target and \c templateMessage belong to this object. User
 *						shouldn't free them or do anything else.
 */
ActivityWindow::ActivityWindow( ActivityData* data,
									 BMessenger* target,
									 BString		 name,
									 Category*	 category,
									 BMessage* templateMessage,
									 bool reminder )
	:
	BWindow( BRect( 0, 0, 400, 500 ),
				"Event occurred",
				B_FLOATING_WINDOW_LOOK,
				B_NORMAL_WINDOW_FEEL,
				B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS ),
	fTarget( target ),
	fData( data ),
	fTemplateMessage( templateMessage ),
	bIsReminder( reminder ),
	fLastError( B_OK ),
	fEventName( name ),
	fCategory( category ),
	fTitle( NULL ),
	fEventNameView( NULL ),
	fCategoryView( NULL ),
	fTextScroller( NULL ),
	fSnoozeTime( NULL ),
	fNoteText( NULL ),
	fSnooze( NULL ),
	fOk( NULL )
{
	BFont boldFont( be_bold_font );
	BFont plainFont( be_plain_font );
	BFont font;			// For various font-related activities
	font_height	fh;	// For setting the height of the Text View with notification text
	plainFont.GetHeight( &fh );
	int	numberOfColumnsInLayout = 2;
	
	// Sanity check
	if ( !data || !target ) {
		/* Panic! */
		fLastError = B_BAD_VALUE;
		return;
	}
	
	if ( ! fData->GetNotification( NULL ) &&
		  ! fData->GetSound( NULL ) &&
		  ! fData->GetProgram( NULL, NULL ) )
	{
		// Nothing to do! This is not an error!
		fLastError = B_NO_INIT;
		return;
	}
	BView*	background = new BView( Bounds(),
												"Background view",
												B_FOLLOW_ALL_SIDES,
												B_WILL_DRAW );
	if ( !background ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	this->AddChild( background );
	BGridLayout* gridLayout = new BGridLayout();
	if ( !gridLayout ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	background->SetLayout( gridLayout );
	background->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
	gridLayout->SetInsets( 5, 5, 5, 5 );
	
	/*-------------------------------------------------
	 * First line - explaining what's happening here
	 *------------------------------------------------*/
	BStringView* exp = new BStringView( BRect( 0, 0, 1, 1 ),
													"Explanation 1",
													( bIsReminder ? 
															"A Reminder has occured!" : 
															"An Event has occured!" ) );
	if ( ! exp ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;	
	}
	exp->SetFont( &boldFont );
	exp->ResizeToPreferred();
	BLayoutItem* layoutItem = gridLayout->AddView( exp, 0, 0, numberOfColumnsInLayout, 1 );
	if ( layoutItem ) {
		layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_CENTER, B_ALIGN_TOP ) );
	}
	
	/*-----------------------------------------------------------------
	 * Second line - event's name on category's color as background
	 *----------------------------------------------------------------*/
	 
	// Create background
	// Note: the pulse is requested for this Window to receive Pulse notifications.
	fBackground = new BView( BRect( 0, 0, 1, 1 ),
									 "Background",
									 B_FOLLOW_LEFT_RIGHT | B_FOLLOW_V_CENTER | B_PULSE_NEEDED,
									 B_WILL_DRAW );
	if ( !fBackground ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	fBackground->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
	layoutItem = gridLayout->AddView( fBackground, 0, 1, numberOfColumnsInLayout, 1 );
	if ( layoutItem ) {
		layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT ) );
	}
	
	BGroupLayout* bgLayout = new BGroupLayout( B_VERTICAL );
	if ( !bgLayout ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	fBackground->SetLayout( bgLayout	);
	bgLayout->SetInsets( 15, 10, 15, 10 );
	fBackground->SetViewColor( fCategory.categoryColor );
	BString sb = "Category:\n";
	sb << fCategory.categoryName;
	fBackground->SetToolTip( sb.String() );
	
	// Create Event's name view
	fTitle = new BStringView( BRect( 0, 0, 1, 1 ),
									  "Event name",
									  fEventName.String(),
									  B_FOLLOW_H_CENTER | B_FOLLOW_V_CENTER );
	if ( !fTitle ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
		// Use big bold font for Event's name
	fTitle->SetFont( be_bold_font );
	fTitle->GetFont( &font );
	font.SetSize( font.Size() + 2 );
	fTitle->SetFont( &font, B_FONT_SIZE );
	
		// Add the title and set its tooltip
	fTitle->ResizeToPreferred();
	fTitle->SetToolTip( sb.String() );
	bgLayout->AddView( fTitle );
	fTitle->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
	fTitle->SetToolTip( fEventName.String() );
	
	int	nextLineInLayout = 2;
	
	/*================================================================
	 * If the notification was set by the user, display it.
	 *================================================================*/

	BString 	tempString;
	BPath		path;
	float rectHeight = fh.leading + fh.ascent + fh.descent;
	float rectWidth = this->Bounds().Width() - 10;		// Layout insets
	BSize size( rectWidth, rectHeight );
	
	if ( fData->GetNotification( &tempString ) )
	{
		/*-----------------------------------------------------------------
	 	 * Line of explanation
	 	 *----------------------------------------------------------------*/
		exp = new BStringView( BRect( 0, 0, 1, 1 ),
									  "Text view explanation",
									  "You set the following notification:" );
		if ( !exp ) {
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return;
		}
		exp->ResizeToPreferred();
		layoutItem = gridLayout->AddView( exp, 0, nextLineInLayout++, numberOfColumnsInLayout, 1 );

		/*-----------------------------------------------------------------
	 	 * Text view with notification text
	 	 *----------------------------------------------------------------*/
		BRect tempRect( BPoint( 0, 0 ), size );
		tempRect.right -= B_V_SCROLL_BAR_WIDTH;
		fNoteText = new BTextView( tempRect,
											"Notification text container",
											tempRect.InsetByCopy( 1, 1 ),
											B_FOLLOW_ALL_SIDES,
											B_WILL_DRAW );
		if ( !fNoteText ) {
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return;
		}
		fNoteText->MakeEditable( false );
		fNoteText->SetText( tempString.String() );
		
		/*-----------------------------------------------------------------
	 	 * Scroll view to scroll the notification text
	 	 *----------------------------------------------------------------*/
		fTextScroller = new BScrollView( "Notification text scroller",
													fNoteText,
													B_FOLLOW_ALL_SIDES,
													0,
													false,
													true );
		if ( !fTextScroller ) {
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return;
		}
		layoutItem = gridLayout->AddView( fTextScroller, 0, nextLineInLayout++, numberOfColumnsInLayout, 1 );
		if ( layoutItem ) {
//			layoutItem->SetExplicitMaxSize( size );
			layoutItem->SetExplicitMinSize( size );
			layoutItem->SetExplicitPreferredSize( size );
			layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT ) );
		}
	}	// <-- end of adding information about the notification
	
	/*================================================================
	 * If user wanted to play a sound file, notify him about it.
	 *================================================================*/
	if ( fData->GetSound( &path ) )
	{
		/*-----------------------------------------------------------------
	 	 * Line of explanation
	 	 *----------------------------------------------------------------*/
		exp = new BStringView( BRect( 0, 0, 1, 1 ),
									  "Sound file explanation",
									  "You wanted to play the file:",
									  B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
		if ( !exp ) {
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return;
		}
		exp->ResizeToPreferred();
		layoutItem = gridLayout->AddView( exp, 0, nextLineInLayout++, numberOfColumnsInLayout, 1 );
		if ( layoutItem ) {
			layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_CENTER, B_ALIGN_MIDDLE ) );
		}

		/*-----------------------------------------------------------------
	 	 * Display sound file name
	 	 *----------------------------------------------------------------*/
	 	 
	 	// What should we display - full path or just the leaf?
	 	if ( ( size.width - 10 ) > plainFont.StringWidth( path.Path() ) )
	 	{
	 		tempString.SetTo( path.Path() );
	 	}
	 	else
	 	{
	 		tempString.SetTo( path.Leaf() );
	 	}
		exp = new BStringView( BRect( 0, 0, 1, 1 ),
									  "Sound file name",
									  tempString.String() );
		if ( !exp ) {
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return;
		}
		exp->ResizeToPreferred();
		layoutItem = gridLayout->AddView( exp, 0, nextLineInLayout++, numberOfColumnsInLayout, 1 );
		if ( layoutItem ) {
			layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_CENTER, B_ALIGN_MIDDLE ) );
		}
		
	}	// <-- end of displaying information about the sound file
	
	/*================================================================
	 * If user wanted to run a program, notify him about it.
	 *================================================================*/
	if ( fData->GetProgram( &path, &tempString ) )
	{
		/*-----------------------------------------------------------------
	 	 * Line of explanation
	 	 *----------------------------------------------------------------*/
		exp = new BStringView( BRect( 0, 0, 1, 1 ),
									  "Program explanation",
									  "You wanted to run a program:" );
		if ( !exp ) {
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return;
		}
		exp->ResizeToPreferred();
		layoutItem = gridLayout->AddView( exp, 0, nextLineInLayout++, numberOfColumnsInLayout, 1 );
		if ( layoutItem ) {
			layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_CENTER, B_ALIGN_MIDDLE ) );
		}

		/*-----------------------------------------------------------------
	 	 * Display path to program file
	 	 *----------------------------------------------------------------*/
	 	 
	 	// What should we display - full path or just the leaf?
	 	exp = new BStringView( BRect( 0, 0, 1, 1 ),
									  "Program file name",
									  ( ( size.width - 10 ) > plainFont.StringWidth( path.Path() ) ) ?
									  		path.Path() :
									  		path.Leaf() );
		if ( !exp ) {
			/* Panic! */
			fLastError = B_NO_MEMORY;
			return;
		}
		exp->ResizeToPreferred();
		layoutItem = gridLayout->AddView( exp, 0, nextLineInLayout++, numberOfColumnsInLayout, 1 );
		if ( layoutItem ) {
			layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_CENTER, B_ALIGN_MIDDLE ) );
		}
		
		/*-----------------------------------------------------------------
	 	 * Explanation about the program options
	 	 *----------------------------------------------------------------*/
	 	 
	 	if ( tempString.Length() > 0 ) {
		 	exp = new BStringView( BRect( 0, 0, 1, 1 ),
										  "Program file options explanation",
										  "With the following parameters:" );
			if ( !exp ) {
				/* Panic! */
				fLastError = B_NO_MEMORY;
				return;
			}
			exp->ResizeToPreferred();
			layoutItem = gridLayout->AddView( exp, 0, nextLineInLayout++, numberOfColumnsInLayout, 1 );
			if ( layoutItem ) {
				layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_CENTER, B_ALIGN_MIDDLE ) );
			}
			
			/*-----------------------------------------------------------------
		 	 * Display the program options
		 	 *----------------------------------------------------------------*/
		 	 
		 	// What should we display - full path or just the leaf?
		 	exp = new BStringView( BRect( 0, 0, 1, 1 ),
										  "Program file options",
										  tempString.String() );
			if ( !exp ) {
				/* Panic! */
				fLastError = B_NO_MEMORY;
				return;
			}
			exp->ResizeToPreferred();
			layoutItem = gridLayout->AddView( exp, 0, nextLineInLayout++, numberOfColumnsInLayout, 1 );
			if ( layoutItem ) {
				layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_CENTER, B_ALIGN_MIDDLE ) );
			}
	 	}	// <-- end of diplaying CLI options		
	}	// <-- end of displaying information about the program to run
	
	/*================================================================
	 * Now it's time to display the Snooze time selector
	 *================================================================*/
	TimePreferences* prefs = pref_GetTimePreferences();
	if ( prefs ) {
		prefs->GetDefaultSnoozeTime( ( int* )&fSnoozeHours, ( int* )&fSnoozeMins );
	} else {
		fSnoozeHours = 0;
		fSnoozeMins = 10;
	}
	
	BMessage* toSend = new BMessage( kSnoozeTimeControlMessage );
	if ( ! toSend ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	fSnoozeTime = new GeneralHourMinControl( BRect( 0, 0, 1, 1 ),
														  "Snooze time selector",
														  "Snooze this Activtiy for:",
														  BString( "" ),	// No check box
														  toSend );
	if ( !fSnoozeTime ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	fSnoozeTime->SetHoursLimit( 23 );	// Max reminder time delay is 23 hours 55 minutes
	fSnoozeTime->SetMinutesLimit( 55 );
	fSnoozeTime->SetCurrentTime( fSnoozeHours, fSnoozeMins );
	
	layoutItem = gridLayout->AddView( fSnoozeTime, 0, nextLineInLayout++, numberOfColumnsInLayout, 1 );
	if ( layoutItem ) {
		layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_CENTER, B_ALIGN_MIDDLE ) );
	}
	

	/*================================================================
	 * Snooze button
	 *================================================================*/
	toSend = new BMessage( kSnoozeButtonPressed );
	if ( !toSend ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	fSnooze = new BButton( BRect( 0, 0, 1, 1 ),
								  "Snooze button",
								  "Snooze",
								  toSend,
								  B_FOLLOW_LEFT | B_FOLLOW_TOP );
	if ( !fSnooze ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	fSnooze->ResizeToPreferred();
	layoutItem = gridLayout->AddView( fSnooze, 0, nextLineInLayout );
	if ( layoutItem ) {
		layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_LEFT, B_ALIGN_TOP ) );
	}

	/*================================================================
	 * Ok button
	 *================================================================*/
	toSend = new BMessage( kDismissButtonPressed );
	if ( !toSend ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	fOk = new BButton( BRect( 0, 0, 1, 1 ),
							  "Dismiss button",
							  "Dismiss",
							  toSend,
							  B_FOLLOW_RIGHT | B_FOLLOW_TOP );
	if ( !fOk ) {
		/* Panic! */
		fLastError = B_NO_MEMORY;
		return;
	}
	fSnooze->ResizeToPreferred();
	layoutItem = gridLayout->AddView( fOk, 1, nextLineInLayout );
	if ( layoutItem ) {
		layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_RIGHT, B_ALIGN_TOP ) );
	}

	this->CenterOnScreen();	
}	// <-- end of constructor for ActivityWindow
/*!	\brief			Constructor of CategoryPreferencesView
 *	\details		It's a descendant of BView.
 *	\param[in]	frame	The frame rectangle of the view.
 */
CategoryPreferencesView::CategoryPreferencesView( BRect frame )
	:
	BView( frame,
		   "Category Preferences",
		   B_FOLLOW_ALL_SIDES,
		   B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE )
{
	BLayoutItem* layoutItem = NULL;
	BMessage* toSend = NULL;
	menuField = NULL;
	
	this->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
	
	/*!	\note	Layout of the view
	 *			The view has a grid layout. It's arranged in the following way:
	 *			1)	Left column - list of Categories (CategoryList) that
	 *				contains all categories currently available.
	 *			2) 	Right column - three buttons, from top to bottom:
	 *				2a)	Edit currently selected category - guess what it's doing
	 *				2b) Add a new category
	 *				2c)	Merge a current directory into another one + menu with
	 *					all categories. The category selected in the list is disabled.
	 * \note	Restrictions:
	 *			a) The list of categories is scrolled.
	 *			b) If no category is selected, then
	 *				i) 	"Edit" button is disabled
	 *				ii)	"Merge to" field is disabled
	 *			
	 */
	BGridLayout* gridLayout = new BGridLayout();
	if ( !gridLayout )
	{
		/* Panic! */
		exit( 1 );
	}
	// Margins from the sides of the view and spacing between the elements
	gridLayout->SetInsets( 5, 5, 5, 5 );
	gridLayout->SetHorizontalSpacing( 10 );
	gridLayout->SetVerticalSpacing( 10 );
	this->SetLayout( gridLayout );
	gridLayout->SetExplicitAlignment( BAlignment( B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT ) );
	gridLayout->SetExplicitMinSize( BSize( (this->Bounds()).Width(), (this->Bounds()).Height() ) );
	

	BRect rect = gridLayout->Frame();
	printf ( "The frame is %d pixels wide and %d pixels high.\n",
			 (int )rect.Width(),
			 (int )rect.Height() );
	
	
	/* Creating the CategoryListView with its scroller */
	BRect r( this->Bounds() );
	r.InsetBySelf( 5, 10 );	// Margins near the border of the view
	r.right = (int)(r.right / 2) - B_V_SCROLL_BAR_WIDTH;
	r.bottom -= 0;
	
	listView = new CategoryListView( r, "List View" );
	if ( ! listView ) {
		/* Panic! */
		exit( 1 );
	}
	BLooper* looper = this->Looper();
	if ( looper && looper->LockLooper() )
	{
		looper->AddHandler( ( BHandler* )this );
		looper->UnlockLooper();	
	}
	
	scroller = new BScrollView( "Scroller",
								listView,
								B_FOLLOW_LEFT | B_FOLLOW_TOP,
								0, 	// Flags
								true,
								true );
	if ( !scroller )
	{
		/* Panic! */
		exit( 1 );
	}
	layoutItem = gridLayout->AddView( scroller, 0, 0, 1, 3 );
	if ( !layoutItem ) {
		/* Panic! */
		exit( 1 );
	}
	layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_LEFT,
												  B_ALIGN_USE_FULL_HEIGHT ) );
	toSend = new BMessage( kCategoryInvoked );
	if ( !toSend )
	{
		/* Panic! */
		exit( 1 );
	}
	listView->SetInvocationMessage( toSend );
	toSend = new BMessage( kCategorySelected );
	if ( !toSend )
	{
		/* Panic! */
		exit( 1 );
	}
	listView->SetSelectionMessage( toSend );
	
	r = listView->Bounds();	
	r.bottom += B_H_SCROLL_BAR_HEIGHT + 3;
	r.right -= ( B_V_SCROLL_BAR_WIDTH + 10 );
	
	layoutItem->SetExplicitMinSize( BSize( ( B_V_SCROLL_BAR_WIDTH * 2 ), r.Height() ) );
	gridLayout->SetMaxColumnWidth( 0, r.Width()-70 );
	gridLayout->SetMaxColumnWidth( 1, r.Width()-66 );
	
	// Add categories to the list
	PopulateCategoriesView();
	
	/* Creating the buttons */
	// Add new category button
	toSend = new BMessage( kAddNewCategory );
	addButton = new BButton( BRect( 0, 0, 1, 1), 
							 "Add category",
							 "Add category",
							 toSend,
							 B_FOLLOW_H_CENTER | B_FOLLOW_V_CENTER );
	if ( !toSend || !addButton ) {
		/* Panic! */
		exit( 1 );
	}
	addButton->ResizeToPreferred();
	addButton->SetTarget( this );
	layoutItem = gridLayout->AddView( addButton, 1, 0, 1, 1 );
	layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER ) );
	
	// Edit old category button
	toSend = new BMessage( kCategoryInvoked );
	editButton = new BButton( BRect( 0, 0, 1, 1), 
							 "Edit category",
							 "Edit category",
							 toSend,
							 B_FOLLOW_H_CENTER | B_FOLLOW_V_CENTER );
	if ( !toSend || !editButton ) {
		/* Panic! */
		exit( 1 );
	}
	editButton->ResizeToPreferred();
	editButton->SetTarget( this );
	layoutItem = gridLayout->AddView( editButton, 1, 1, 1, 1 );
	layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER ) );
	// Edit category button is disabled by default; 
	// it's enabled when user chooses a category in the list.
	editButton->SetEnabled( false );
	
	/* Creating the menu of merging a category */
	// Create a label
	BGroupLayout* groupLayout = new BGroupLayout( B_VERTICAL );
	if ( !groupLayout )
	{
		/* Panic! */
		exit( 1 );
	}
	gridLayout->AddItem( groupLayout, 1, 2, 1, 1 );
	groupLayout->SetExplicitAlignment( BAlignment( B_ALIGN_LEFT, B_ALIGN_TOP ) );
	
	mergeToLabel = new BStringView( BRect( 0, 0, 1, 1 ),
								"Merge to label",
								"Merge selected category into:" );
	if ( !mergeToLabel ) {
		/* Panic! */
		exit( 1 );
	}
	mergeToLabel->ResizeToPreferred();
	layoutItem = groupLayout->AddView( mergeToLabel );
	layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_LEFT, B_ALIGN_TOP ) );
	
	// Create the menu
	BMessage templateMessage( kMergeIntoCategory );
	listMenu = new CategoryMenu( "Select category to merge to:", true, &templateMessage );
	if ( !listMenu )
	{
		/* Panic! */
		exit( 1 );
	}	
	
	menuField = new BMenuField( mergeToLabel->Bounds(),
								"Merge to field",
								NULL,
								listMenu );
	if ( !menuField ) {
		/* Panic! */
		exit( 1 );
	}
	menuField->SetDivider( 0 );
	// Just like the "Edit" button above, the menu is initially disabled.
	menuField->SetEnabled( false );
	
	layoutItem = groupLayout->AddView( menuField );
	layoutItem->SetExplicitAlignment( BAlignment( B_ALIGN_USE_FULL_WIDTH, B_ALIGN_TOP ) );
	
	for ( int index = 0; index < gridLayout->CountColumns(); ++index )
	{
		gridLayout->SetColumnWeight( index, 1 );
	}
	for ( int index = 0; index < gridLayout->CountRows(); ++index )
	{
		gridLayout->SetRowWeight( index, 1 );	
	}
	gridLayout->InvalidateLayout();
	
}	// <-- end of constructor of CategoryPreferencesView