//-------------------------------------------------------------------- // // PeopleView.cpp // // Written by: Robert Polic // //-------------------------------------------------------------------- /* Copyright 1999, Be Incorporated. All Rights Reserved. This file may be used under the terms of the Be Sample Code License. */ #include #include #include #include #include #include #include #include #include #include #include #include "PeopleView.h" #include "TTextControl.h" //==================================================================== TPeopleView::TPeopleView(BRect rect, char *title, entry_ref *ref) :BView(rect, title, B_FOLLOW_ALL, B_WILL_DRAW) { if (ref) fFile = new BFile(ref, O_RDWR); else fFile = NULL; } //-------------------------------------------------------------------- TPeopleView::~TPeopleView(void) { if (fFile) delete fFile; } //-------------------------------------------------------------------- void TPeopleView::AttachedToWindow(void) { char *text; float offset; BBox *box; BFont font = *be_plain_font; BMenuField *field; BRect r; rgb_color c; attr_info info; c.red = c.green = c.blue = VIEW_COLOR; SetViewColor(c); r = Bounds(); r.InsetBy(-1, -1); box = new BBox(r); AddChild(box); offset = font.StringWidth(HPHONE_TEXT) + 18; text = (char *)malloc(1); text[0] = 0; r.Set(offset - font.StringWidth(NAME_TEXT) - 11, NAME_V, NAME_H + NAME_WIDTH, NAME_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_NAME, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_NAME, B_STRING_TYPE, 0, text, info.size); } } fField[F_NAME] = new TTextControl(r, NAME_TEXT, 256, text, M_DIRTY, M_NAME); fField[F_NAME]->SetTarget(this); box->AddChild(fField[F_NAME]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(offset - font.StringWidth(NICKNAME_TEXT) - 11, NICKNAME_V, NICKNAME_H + NICKNAME_WIDTH, NICKNAME_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_NICKNAME, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_NICKNAME, B_STRING_TYPE, 0, text, info.size); } } fField[F_NICKNAME] = new TTextControl(r, NICKNAME_TEXT, 256, text, M_DIRTY, M_NICKNAME); fField[F_NICKNAME]->SetTarget(this); box->AddChild(fField[F_NICKNAME]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(offset - font.StringWidth(COMPANY_TEXT) - 11, COMPANY_V, COMPANY_H + COMPANY_WIDTH, COMPANY_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_COMPANY, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_COMPANY, B_STRING_TYPE, 0, text, info.size); } } fField[F_COMPANY] = new TTextControl(r, COMPANY_TEXT, 256, text, M_DIRTY, M_COMPANY); fField[F_COMPANY]->SetTarget(this); box->AddChild(fField[F_COMPANY]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(offset - font.StringWidth(ADDRESS_TEXT) - 11, ADDRESS_V, ADDRESS_H + ADDRESS_WIDTH, ADDRESS_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_ADDRESS, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_ADDRESS, B_STRING_TYPE, 0, text, info.size); } } fField[F_ADDRESS] = new TTextControl(r, ADDRESS_TEXT, 256, text, M_DIRTY, M_ADDRESS); fField[F_ADDRESS]->SetTarget(this); box->AddChild(fField[F_ADDRESS]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(offset - font.StringWidth(CITY_TEXT) - 11, CITY_V, CITY_H + CITY_WIDTH, CITY_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_CITY, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_CITY, B_STRING_TYPE, 0, text, info.size); } } fField[F_CITY] = new TTextControl(r, CITY_TEXT, 256, text, M_DIRTY, M_CITY); fField[F_CITY]->SetTarget(this); box->AddChild(fField[F_CITY]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(offset - font.StringWidth(STATE_TEXT) - 11, STATE_V, STATE_H + STATE_WIDTH, STATE_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_STATE, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_STATE, B_STRING_TYPE, 0, text, info.size); } } fField[F_STATE] = new TTextControl(r, STATE_TEXT, 256, text, M_DIRTY, M_STATE); fField[F_STATE]->SetTarget(this); box->AddChild(fField[F_STATE]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(ZIP_H + 11, ZIP_V, ZIP_H + ZIP_WIDTH, ZIP_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_ZIP, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_ZIP, B_STRING_TYPE, 0, text, info.size); } } fField[F_ZIP] = new TTextControl(r, ZIP_TEXT, 256, text, M_DIRTY, M_ZIP); fField[F_ZIP]->SetTarget(this); box->AddChild(fField[F_ZIP]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(offset - font.StringWidth(COUNTRY_TEXT) - 11, COUNTRY_V, COUNTRY_H + COUNTRY_WIDTH, COUNTRY_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_COUNTRY, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_COUNTRY, B_STRING_TYPE, 0, text, info.size); } } fField[F_COUNTRY] = new TTextControl(r, COUNTRY_TEXT, 256, text, M_DIRTY, M_COUNTRY); fField[F_COUNTRY]->SetTarget(this); box->AddChild(fField[F_COUNTRY]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(offset - font.StringWidth(HPHONE_TEXT) - 11, HPHONE_V, HPHONE_H + HPHONE_WIDTH, HPHONE_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_HPHONE, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_HPHONE, B_STRING_TYPE, 0, text, info.size); } } fField[F_HPHONE] = new TTextControl(r, HPHONE_TEXT, 256, text, M_DIRTY, M_HPHONE); fField[F_HPHONE]->SetTarget(this); box->AddChild(fField[F_HPHONE]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(offset - font.StringWidth(WPHONE_TEXT) - 11, WPHONE_V, WPHONE_H + WPHONE_WIDTH, WPHONE_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_WPHONE, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_WPHONE, B_STRING_TYPE, 0, text, info.size); } } fField[F_WPHONE] = new TTextControl(r, WPHONE_TEXT, 256, text, M_DIRTY, M_WPHONE); fField[F_WPHONE]->SetTarget(this); box->AddChild(fField[F_WPHONE]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(offset - font.StringWidth(FAX_TEXT) - 11, FAX_V, FAX_H + FAX_WIDTH, FAX_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_FAX, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_FAX, B_STRING_TYPE, 0, text, info.size); } } fField[F_FAX] = new TTextControl(r, FAX_TEXT, 256, text, M_DIRTY, M_FAX); fField[F_FAX]->SetTarget(this); box->AddChild(fField[F_FAX]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(offset - font.StringWidth(EMAIL_TEXT) - 11, EMAIL_V, EMAIL_H + EMAIL_WIDTH, EMAIL_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_EMAIL, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_EMAIL, B_STRING_TYPE, 0, text, info.size); } } fField[F_EMAIL] = new TTextControl(r, EMAIL_TEXT, 256, text, M_DIRTY, M_EMAIL); fField[F_EMAIL]->SetTarget(this); box->AddChild(fField[F_EMAIL]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(offset - font.StringWidth(URL_TEXT) - 11, URL_V, URL_H + URL_WIDTH, URL_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_URL, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_URL, B_STRING_TYPE, 0, text, info.size); } } fField[F_URL] = new TTextControl(r, URL_TEXT, 256, text, M_DIRTY, M_URL); fField[F_URL]->SetTarget(this); box->AddChild(fField[F_URL]); text = (char *)realloc(text, 1); text[0] = 0; r.Set(offset - 11, GROUP_V, GROUP_H + GROUP_WIDTH, GROUP_V + TEXT_HEIGHT); if (fFile) { if (fFile->GetAttrInfo(P_GROUP, &info) == B_NO_ERROR) { text = (char *)realloc(text, info.size); fFile->ReadAttr(P_GROUP, B_STRING_TYPE, 0, text, info.size); } } fField[F_GROUP] = new TTextControl(r, "", 256, text, M_DIRTY, M_GROUP); fField[F_GROUP]->SetTarget(this); box->AddChild(fField[F_GROUP]); free(text); r.right = r.left + 3; r.left = r.right - font.StringWidth(GROUP_TEXT) - 20; r.top -= 1; fGroups = new BPopUpMenu("Group"); fGroups->SetRadioMode(FALSE); field = new BMenuField(r, "", "", fGroups); field->SetDivider(0.0); field->SetFont(&font); field->SetEnabled(TRUE); box->AddChild(field); fField[F_NAME]->MakeFocus(); } //-------------------------------------------------------------------- void TPeopleView::MessageReceived(BMessage* msg) { int32 loop; BTextView *text; switch (msg->what) { case M_SAVE: Save(); break; case M_REVERT: for (loop = 0; loop < F_END; loop++) fField[loop]->Revert(); break; case M_SELECT: for (loop = 0; loop < F_END; loop++) { text = (BTextView *)fField[loop]->ChildAt(0); if (text->IsFocus()) { text->Select(0, text->TextLength()); break; } } break; } } //-------------------------------------------------------------------- void TPeopleView::BuildGroupMenu(void) { char *offset; char str[256]; char *text; char *text1; int32 count = 0; int32 index; BEntry entry; BFile file; BMessage *msg; BMenuItem *item; BQuery query; BVolume vol; BVolumeRoster volume; attr_info info; while ((item = fGroups->ItemAt(0))) { fGroups->RemoveItem(item); delete item; } volume.GetBootVolume(&vol); query.SetVolume(&vol); sprintf(str, "%s=*", P_GROUP); query.SetPredicate(str); query.Fetch(); while (query.GetNextEntry(&entry) == B_NO_ERROR) { file.SetTo(&entry, O_RDONLY); if ((file.InitCheck() == B_NO_ERROR) && (file.GetAttrInfo(P_GROUP, &info) == B_NO_ERROR) && (info.size > 1)) { text = (char *)malloc(info.size); text1 = text; file.ReadAttr(P_GROUP, B_STRING_TYPE, 0, text, info.size); while (1) { if ((offset = strstr(text, ","))) *offset = 0; if (!fGroups->FindItem(text)) { index = 0; while ((item = fGroups->ItemAt(index))) { if (strcmp(text, item->Label()) < 0) break; index++; } msg = new BMessage(M_GROUP_MENU); msg->AddString("group", text); fGroups->AddItem(new BMenuItem(text, msg), index); count++; } if (offset) { text = offset + 1; while (*text == ' ') text++; } else break; } free(text1); } } if (!count) { fGroups->AddItem(item = new BMenuItem("none", new BMessage(M_GROUP_MENU))); item->SetEnabled(FALSE); } } //-------------------------------------------------------------------- bool TPeopleView::CheckSave(void) { int32 loop; for (loop = 0; loop < F_END; loop++) if (fField[loop]->Changed()) return TRUE; return FALSE; } //-------------------------------------------------------------------- const char* TPeopleView::GetField(int32 index) { if (index < F_END) return fField[index]->Text(); else return NULL; } //-------------------------------------------------------------------- void TPeopleView::NewFile(entry_ref *ref) { if (fFile) delete fFile; fFile = new BFile(ref, O_RDWR); Save(); } //-------------------------------------------------------------------- void TPeopleView::Save(void) { const char *text; text = fField[F_NAME]->Text(); fFile->WriteAttr(P_NAME, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_NAME]->Update(); text = fField[F_COMPANY]->Text(); fFile->WriteAttr(P_COMPANY, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_COMPANY]->Update(); text = fField[F_ADDRESS]->Text(); fFile->WriteAttr(P_ADDRESS, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_ADDRESS]->Update(); text = fField[F_CITY]->Text(); fFile->WriteAttr(P_CITY, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_CITY]->Update(); text = fField[F_STATE]->Text(); fFile->WriteAttr(P_STATE, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_STATE]->Update(); text = fField[F_ZIP]->Text(); fFile->WriteAttr(P_ZIP, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_ZIP]->Update(); text = fField[F_COUNTRY]->Text(); fFile->WriteAttr(P_COUNTRY, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_COUNTRY]->Update(); text = fField[F_HPHONE]->Text(); fFile->WriteAttr(P_HPHONE, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_HPHONE]->Update(); text = fField[F_WPHONE]->Text(); fFile->WriteAttr(P_WPHONE, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_WPHONE]->Update(); text = fField[F_FAX]->Text(); fFile->WriteAttr(P_FAX, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_FAX]->Update(); text = fField[F_EMAIL]->Text(); fFile->WriteAttr(P_EMAIL, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_EMAIL]->Update(); text = fField[F_URL]->Text(); fFile->WriteAttr(P_URL, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_URL]->Update(); text = fField[F_GROUP]->Text(); fFile->WriteAttr(P_GROUP, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_GROUP]->Update(); text = fField[F_NICKNAME]->Text(); fFile->WriteAttr(P_NICKNAME, B_STRING_TYPE, 0, text, strlen(text) + 1); fField[F_NICKNAME]->Update(); } //-------------------------------------------------------------------- void TPeopleView::SetField(int32 index, char *data, bool update) { int32 end; int32 start; BTextView *text; Window()->Lock(); if (update) { fField[index]->SetText(data); fField[index]->Update(); } else { text = (BTextView *)fField[index]->ChildAt(0); text->GetSelection(&start, &end); if (start != end) { text->Delete(); text->Insert(data); } else if ((end = text->TextLength())) { text->Select(end, end); text->Insert(","); text->Insert(data); text->Select(text->TextLength(), text->TextLength()); } else fField[index]->SetText(data); } Window()->Unlock(); } //-------------------------------------------------------------------- bool TPeopleView::TextSelected(void) { int32 end; int32 loop; int32 start; BTextView *text; for (loop = 0; loop < F_END; loop++) { text = (BTextView *)fField[loop]->ChildAt(0); text->GetSelection(&start, &end); if (start != end) return TRUE; } return FALSE; }