#include "FilterView.h"
#include <algorithm>
#include <stdio.h>
#include <AutoLocker.h>
#include <Catalog.h>
#include <CheckBox.h>
#include <LayoutBuilder.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <Messenger.h>
#include <PopUpMenu.h>
#include <TextControl.h>
#include "Model.h"
#include "support.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "FilterView"
const char* const filter_view_keys::kKeySearchTerms = "search_terms";
FilterView::FilterView()
:
BGroupView("filter view", B_VERTICAL)
{
BPopUpMenu* showMenu = new BPopUpMenu(B_TRANSLATE("Category"));
fShowField = new BMenuField("category", B_TRANSLATE("Category:"), showMenu);
fSearchTermsText = new BTextControl("search terms", B_TRANSLATE("Search terms:"), "", NULL);
fSearchTermsText->SetModificationMessage(new BMessage(MSG_SEARCH_TERMS_MODIFIED));
BSize minSearchSize = fSearchTermsText->MinSize();
float minSearchWidth = be_plain_font->StringWidth(fSearchTermsText->Label())
+ be_plain_font->StringWidth("XXX") * 6;
minSearchWidth = std::max(minSearchSize.width, minSearchWidth);
minSearchSize.width = minSearchWidth;
fSearchTermsText->SetExplicitMinSize(minSearchSize);
float maxSearchWidth = minSearchWidth * 2;
fSearchTermsText->SetExplicitMaxSize(BSize(maxSearchWidth, B_SIZE_UNSET));
BLayoutBuilder::Group<>(this)
.AddGroup(B_HORIZONTAL)
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING, 1.2f)
.Add(fShowField, 0.0f)
.SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET))
.End()
.AddGlue(0.5f)
.Add(fSearchTermsText, 1.0f)
.End()
.SetInsets(B_USE_DEFAULT_SPACING)
;
}
FilterView::~FilterView()
{
}
void
FilterView::AttachedToWindow()
{
fShowField->Menu()->SetTargetForItems(Window());
fSearchTermsText->SetTarget(this);
fSearchTermsText->MakeFocus();
}
void
FilterView::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_SEARCH_TERMS_MODIFIED:
{
BMessage searchTerms(MSG_SEARCH_TERMS_MODIFIED);
searchTerms.AddString(filter_view_keys::kKeySearchTerms, fSearchTermsText->Text());
Window()->PostMessage(&searchTerms);
break;
}
default:
BGroupView::MessageReceived(message);
break;
}
}
void
FilterView::AdoptModel(Model& model)
{
BMenu* showMenu = fShowField->Menu();
showMenu->RemoveItems(0, showMenu->CountItems(), true);
showMenu->AddItem(
new BMenuItem(B_TRANSLATE("All categories"), new BMessage(MSG_CATEGORY_SELECTED)));
if (model.HasCategories()) {
showMenu->AddItem(new BSeparatorItem());
_AddCategoriesToMenu(model, showMenu);
showMenu->SetEnabled(true);
} else {
showMenu->SetEnabled(false);
}
if (!_SelectCategoryCode(showMenu, model.FilterSpecification()->Category()))
showMenu->ItemAt(0)->SetMarked(true);
}
bool
FilterView::_SelectCategoryCode(BMenu* menu, const BString& code)
{
for (int32 i = 0; i < menu->CountItems(); i++) {
BMenuItem* item = menu->ItemAt(i);
if (_MatchesCategoryCode(item, code)) {
item->SetMarked(true);
return true;
}
}
return false;
}
bool
FilterView::_MatchesCategoryCode(BMenuItem* item, const BString& code)
{
BMessage* message = item->Message();
if (message == NULL)
return false;
BString itemCode;
message->FindString(shared_message_keys::kKeyCode, &itemCode);
return itemCode == code;
}
void
FilterView::_AddCategoriesToMenu(Model& model, BMenu* menu)
{
std::vector<CategoryRef> categories = model.Categories();
std::vector<CategoryRef>::const_iterator it;
for (it = categories.begin(); it != categories.end(); it++) {
const CategoryRef& category = *it;
BMessage* message = new BMessage(MSG_CATEGORY_SELECTED);
message->AddString(shared_message_keys::kKeyCode, category->Code());
BMenuItem* item = new BMenuItem(category->Name(), message);
menu->AddItem(item);
}
}