void CatBrowser::SetupQuery(void) { BString command, esccat = EscapeIllegalCharacters(fCategory.String()); CppSQLite3Query query; command = "select count(number) from "; command << esccat << ";"; query = DBQuery(command.String(), "CatBrowser::SetupQuery:get category count"); fCategoryCount = (query.eof()) ? 0 : query.getIntField(0); for(int32 i = 0; i < fPageList.CountItems(); i++) { QueryPage *page = (QueryPage*)fPageList.ItemAt(i); page->MakeEmpty(); } fPageCount = (fCategoryCount / BROWSE_MODE_RECIPE_COUNT); if( (fPageCount % BROWSE_MODE_RECIPE_COUNT) || fPageCount < BROWSE_MODE_RECIPE_COUNT) fPageCount++; if(fPageList.CountItems() < fPageCount) { for(int32 i = fPageList.CountItems(); i <= fPageCount; i++) fPageList.AddItem(new QueryPage()); } fCurrentPage = -1; }
status_t LoadRules(const char *path, BObjectList<FilerRule> *ruleList) { BEntry entry("/boot/home/config/settings/FilerRules"); if (!entry.Exists()) return B_OK; CppSQLite3DB db; db.open("/boot/home/config/settings/FilerRules"); // Because this particular build of sqlite3 does not support multithreading // because of lack of pthreads support, we need to do this in a slightly different order CppSQLite3Query query; query = DBQuery(db,"select name from RuleList order by ruleid;","PrefsWindow::LoadRules"); BString command; while (!query.eof()) { BString rulename = query.getStringField((int)0); FilerRule *rule = new FilerRule; rule->SetDescription(DeescapeIllegalCharacters(rulename.String()).String()); ruleList->AddItem(rule); query.nextRow(); } query.finalize(); for (int32 i = 0; i < ruleList->CountItems(); i++) { FilerRule *rule = ruleList->ItemAt(i); if (!rule) continue; BString rulename(EscapeIllegalCharacters(rule->GetDescription())); // Now comes the fun(?) part: loading the tests and actions. Joy. :/ command = "select * from "; command << rulename << " where entrytype = 'test';"; query = DBQuery(db,command.String(),"PrefsWindow::LoadRules"); while (!query.eof()) { BString classname = DeescapeIllegalCharacters(query.getStringField(1)); BMessage *test = new BMessage; test->AddString("name",classname); if (classname.ICompare("Attribute") == 0) { test->AddString("mimetype",DeescapeIllegalCharacters(query.getStringField(4))); test->AddString("typename",DeescapeIllegalCharacters(query.getStringField(5))); test->AddString("attrname",DeescapeIllegalCharacters(query.getStringField(6))); } test->AddString("mode",DeescapeIllegalCharacters(query.getStringField(2)).String()); test->AddString("value",DeescapeIllegalCharacters(query.getStringField(3)).String()); rule->AddTest(test); query.nextRow(); } query.finalize(); command = "select * from "; command << rulename << " where entrytype = 'action';"; query = DBQuery(db,command.String(),"PrefsWindow::LoadRules"); while (!query.eof()) { BMessage *action = new BMessage; action->AddString("name",DeescapeIllegalCharacters(query.getStringField(1))); action->AddString("value",DeescapeIllegalCharacters(query.getStringField(3))); rule->AddAction(action); query.nextRow(); } query.finalize(); } db.close(); return B_OK; }
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())); }
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); }
void CatBrowser::RunQuery(void) { BString esccat(EscapeIllegalCharacters(fCategory.String())); if(fCategory.CountChars() < 1) return; fList->DeselectAll(); for(int32 i = 0; i < fList->CountItems(); i++) { RecipeItem *item = (RecipeItem*)fList->ItemAt(i); delete item; } fList->MakeEmpty(); if(!fCategoryCount) return; int32 itemcount = fEditMode ? EDIT_MODE_RECIPE_COUNT : BROWSE_MODE_RECIPE_COUNT; BString command; CppSQLite3Query query; if(fCurrentPage >= 0) { QueryPage *page = (QueryPage*)fPageList.ItemAt(fCurrentPage); QueryPage *lastpage = NULL; if(!page) return; command = "select * from "; if(page->init) { command << esccat << " where (number >= " << page->start << ") and (number <= " << page->end << ") " << fSortString << ";"; } else { lastpage = (QueryPage*)fPageList.ItemAt(fCurrentPage - 1); command << esccat << " where number >= " << (lastpage->end + 1) << fSortString << ";"; } query = DBQuery(command.String(), "CatBrowser:get category"); RecipeItem *ritem = NULL; for(int32 i = 0; i < itemcount; i++) { if(query.eof()) break; BString string = query.getStringField(1); ritem = new RecipeItem(DeescapeIllegalCharacters(string.String()).String(), esccat.String(), query.getIntField(0)); fList->AddItem(ritem); query.nextRow(); } if(lastpage && ritem) { page->start = lastpage->end + 1; page->end = ritem->fNumber; page->init = true; } } else { command = "select * from "; command << esccat << " where number >= 0 " << fSortString << ";"; query = DBQuery(command.String(), "CatBrowser:get category"); RecipeItem *ritem = NULL; for(int32 i = 0; i < itemcount; i++) { if(query.eof()) break; BString string = query.getStringField(1); ritem = new RecipeItem(DeescapeIllegalCharacters(string.String()).String(), esccat.String(), query.getIntField(0)); fList->AddItem(ritem); query.nextRow(); } if(ritem) { fCurrentPage = 0; QueryPage *page = (QueryPage*)fPageList.ItemAt(fCurrentPage); page->start = 0; page->end = ritem->fNumber; page->init = true; } } fList->Select(0L); fList->MakeFocus(true); }