haiku/src/apps/people/PeopleView.cpp
shatty faef1e5413 from sample code
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1676 a95241bf-73f2-0310-859d-f6bbb57e9c96
2002-10-26 03:33:06 +00:00

539 lines
14 KiB
C++

//--------------------------------------------------------------------
//
// 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 <fs_attr.h>
#include <Window.h>
#include <Box.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <PopUpMenu.h>
#include <Query.h>
#include <VolumeRoster.h>
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#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;
}