diff --git a/src/apps/people/AttributeTextControl.cpp b/src/apps/people/AttributeTextControl.cpp new file mode 100644 index 0000000000..ea9662f7fe --- /dev/null +++ b/src/apps/people/AttributeTextControl.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2005-2010, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Robert Polic + * + * Copyright 1999, Be Incorporated. All Rights Reserved. + * This file may be used under the terms of the Be Sample Code License. + */ + + +#include "AttributeTextControl.h" + +#include +#include +#include + + +AttributeTextControl::AttributeTextControl(const char* label, + const char* attribute) + : + BTextControl(NULL, "", NULL), + fAttribute(attribute), + fOriginalValue() +{ + if (label != NULL && label[0] != 0) + SetLabel(BString(label).Append(":")); + SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); +} + + +AttributeTextControl::~AttributeTextControl() +{ +} + + +bool +AttributeTextControl::HasChanged() +{ + return fOriginalValue != Text(); +} + + +void +AttributeTextControl::Revert() +{ + if (HasChanged()) + SetText(fOriginalValue); +} + + +void +AttributeTextControl::Update() +{ + fOriginalValue = Text(); +} diff --git a/src/apps/people/AttributeTextControl.h b/src/apps/people/AttributeTextControl.h new file mode 100644 index 0000000000..b29cbfaadf --- /dev/null +++ b/src/apps/people/AttributeTextControl.h @@ -0,0 +1,36 @@ +/* + * Copyright 2005-2010, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Robert Polic + * + * Copyright 1999, Be Incorporated. All Rights Reserved. + * This file may be used under the terms of the Be Sample Code License. + */ +#ifndef TEXT_CONTROL_H +#define TEXT_CONTROL_H + +#include +#include + + +class AttributeTextControl : public BTextControl { +public: + AttributeTextControl(const char* label, + const char* attribute); + virtual ~AttributeTextControl(); + + bool HasChanged(); + void Revert(); + void Update(); + + const BString& Attribute() const + { return fAttribute; } + +private: + BString fAttribute; + BString fOriginalValue; +}; + +#endif // TEXT_CONTROL_H diff --git a/src/apps/people/Jamfile b/src/apps/people/Jamfile index b1675c1d06..1e92ae6782 100644 --- a/src/apps/people/Jamfile +++ b/src/apps/people/Jamfile @@ -1,10 +1,12 @@ SubDir HAIKU_TOP src apps people ; +UsePrivateHeaders shared ; + Application People : main.cpp + AttributeTextControl.cpp PeopleApp.cpp PeopleView.cpp PeopleWindow.cpp - TTextControl.cpp : libbe.so libtracker.so $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS) : People.rdef ; diff --git a/src/apps/people/PeopleApp.cpp b/src/apps/people/PeopleApp.cpp index 60f0c69831..3a9315d4b7 100644 --- a/src/apps/people/PeopleApp.cpp +++ b/src/apps/people/PeopleApp.cpp @@ -1,10 +1,11 @@ /* - * Copyright 2005-2009, Haiku, Inc. All rights reserved. + * Copyright 2005-2010, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT license. * * Authors: * Robert Polic * Axel Dörfler, axeld@pinc-software.de + * Stephan Aßmus * * Copyright 1999, Be Incorporated. All Rights Reserved. * This file may be used under the terms of the Be Sample Code License. @@ -12,6 +13,7 @@ #include +#include #include #include #include @@ -34,8 +36,18 @@ #define B_TRANSLATE_CONTEXT "People" -struct people_field gFields[] = { - { "META:name", 120, B_TRANSLATE("Contact name") }, +struct DefaultAttribute { + const char* attribute; + int32 width; + const char* name; +}; + +// TODO: Add flags in attribute info message to find these. +static const char* kNameAttribute = "META:name"; +static const char* kCategoryAttribute = "META:group"; + +struct DefaultAttribute sDefaultAttributes[] = { + { kNameAttribute, 120, B_TRANSLATE("Contact name") }, { "META:nickname", 120, B_TRANSLATE("Nickname") }, { "META:company", 120, B_TRANSLATE("Company") }, { "META:address", 120, B_TRANSLATE("Address") }, @@ -48,16 +60,19 @@ struct people_field gFields[] = { { "META:fax", 90, B_TRANSLATE("Fax") }, { "META:email", 120, B_TRANSLATE("E-mail") }, { "META:url", 120, B_TRANSLATE("URL") }, - { "META:group", 120, B_TRANSLATE("Group") }, + { kCategoryAttribute, 120, B_TRANSLATE("Group") }, { NULL, 0, NULL } }; -TPeopleApp::TPeopleApp(void) - : BApplication(APP_SIG), - fWindowCount(0) +TPeopleApp::TPeopleApp() + : + BApplication(APP_SIG), + fWindowCount(0), + fAttributes(20, true) { - fPosition.Set(6, TITLE_BAR_HEIGHT, 6 + WIND_WIDTH, TITLE_BAR_HEIGHT + WIND_HEIGHT); + fPosition.Set(6, TITLE_BAR_HEIGHT, 6 + WIND_WIDTH, + TITLE_BAR_HEIGHT + WIND_HEIGHT); BPoint pos = fPosition.LeftTop(); BPath path; @@ -65,7 +80,7 @@ TPeopleApp::TPeopleApp(void) BDirectory dir(path.Path()); BEntry entry; - if (dir.FindEntry("People_data", &entry) == B_NO_ERROR) { + if (dir.FindEntry("People_data", &entry) == B_OK) { fPrefs = new BFile(&entry, B_READ_WRITE); if (fPrefs->InitCheck() == B_NO_ERROR) { fPrefs->Read(&pos, sizeof(BPoint)); @@ -74,23 +89,15 @@ TPeopleApp::TPeopleApp(void) } } else { fPrefs = new BFile(); - if (dir.CreateFile("People_data", fPrefs) != B_NO_ERROR) { + if (dir.CreateFile("People_data", fPrefs) != B_OK) { delete fPrefs; fPrefs = NULL; } } - // create indices on all volumes - - BVolumeRoster volumeRoster; - BVolume volume; - while (volumeRoster.GetNextVolume(&volume) == B_OK) { - for (int32 i = 0; gFields[i].attribute; i++) { - fs_create_index(volume.Device(), gFields[i].attribute, B_STRING_TYPE, 0); - } - } - - // install person mime type + // Read attributes from person mime type. If it does not exist, + // or if it contains no attribute definitions, install a "clean" + // person mime type from the hard-coded default attributes. bool valid = false; BMimeType mime; @@ -99,17 +106,42 @@ TPeopleApp::TPeopleApp(void) if (mime.IsInstalled()) { BMessage info; if (mime.GetAttrInfo(&info) == B_NO_ERROR) { - const char *string; int32 index = 0; - while (info.FindString("attr:name", index++, &string) == B_OK) { - if (!strcmp(string, gFields[0].attribute)) { - valid = true; + while (true) { + int32 type; + if (info.FindInt32("attr:type", index, &type) != B_OK) + break; + bool editable; + if (info.FindBool("attr:editable", index, &editable) != B_OK) + break; + + // TODO: Support other types besides string attributes. + if (type != B_STRING_TYPE || !editable) + break; + + Attribute* attribute = new Attribute(); + ObjectDeleter deleter(attribute); + if (info.FindString("attr:public_name", index, + &attribute->name) != B_OK) { break; } + if (info.FindString("attr:name", index, + &attribute->attribute) != B_OK) { + break; + } + + if (!fAttributes.AddItem(attribute)) + break; + + deleter.Detach(); + index++; } - if (!valid) - mime.Delete(); } + if (fAttributes.CountItems() == 0) { + valid = false; + mime.Delete(); + } else + valid = true; } if (!valid) { mime.Install(); @@ -121,154 +153,185 @@ TPeopleApp::TPeopleApp(void) mime.SetIcon(kPersonIcon, sizeof(kPersonIcon)); mime.SetPreferredApp(APP_SIG); - // add relevant person fields to meta-mime type - + // add default person fields to meta-mime type BMessage fields; - for (int32 i = 0; gFields[i].attribute; i++) { - fields.AddString("attr:public_name", gFields[i].name); - fields.AddString("attr:name", gFields[i].attribute); + for (int32 i = 0; sDefaultAttributes[i].attribute; i++) { + fields.AddString("attr:public_name", sDefaultAttributes[i].name); + fields.AddString("attr:name", sDefaultAttributes[i].attribute); fields.AddInt32("attr:type", B_STRING_TYPE); fields.AddBool("attr:viewable", true); fields.AddBool("attr:editable", true); - fields.AddInt32("attr:width", gFields[i].width); + fields.AddInt32("attr:width", sDefaultAttributes[i].width); fields.AddInt32("attr:alignment", B_ALIGN_LEFT); fields.AddBool("attr:extra", false); + + // Add the default attribute to the attribute list, too. + Attribute* attribute = new Attribute(); + attribute->name = sDefaultAttributes[i].name; + attribute->attribute = sDefaultAttributes[i].attribute; + if (!fAttributes.AddItem(attribute)) + delete attribute; } mime.SetAttrInfo(&fields); } + + // create indices on all volumes for the found attributes. + + int32 count = fAttributes.CountItems(); + BVolumeRoster volumeRoster; + BVolume volume; + while (volumeRoster.GetNextVolume(&volume) == B_OK) { + for (int32 i = 0; i < count; i++) { + Attribute* attribute = fAttributes.ItemAt(i); + fs_create_index(volume.Device(), attribute->attribute, + B_STRING_TYPE, 0); + } + } + } -TPeopleApp::~TPeopleApp(void) +TPeopleApp::~TPeopleApp() { delete fPrefs; } void -TPeopleApp::AboutRequested(void) +TPeopleApp::AboutRequested() { - (new BAlert("", "...by Robert Polic", B_TRANSLATE("OK")))->Go(); + (new BAlert(B_TRANSLATE("About"), B_UTF8_ELLIPSIS "by Robert Polic", + B_TRANSLATE("OK")))->Go(); } void -TPeopleApp::ArgvReceived(int32 argc, char **argv) +TPeopleApp::ArgvReceived(int32 argc, char** argv) { - TPeopleWindow* window = NULL; + BMessage message(B_REFS_RECEIVED); - for (int32 loop = 1; loop < argc; loop++) { - char* arg = argv[loop]; - - int32 index; - for (index = 0; gFields[index].attribute; index++) { - if (!strncmp(gFields[index].attribute, arg, strlen(gFields[index].attribute))) - break; - } - - if (gFields[index].attribute != NULL) { - if (!window) - window = NewWindow(); - - while (arg[0] && arg[0] != ' ' && arg[0] != '=') - arg++; - - if (arg[0]) { - arg++; - window->SetField(index, arg); - } - } + for (int32 i = 1; i < argc; i++) { + BEntry entry(argv[i]); + entry_ref ref; + if (entry.Exists() && entry.GetRef(&ref) == B_OK) + message.AddRef("refs", &ref); } + + RefsReceived(&message); } void -TPeopleApp::MessageReceived(BMessage *msg) +TPeopleApp::MessageReceived(BMessage* message) { - switch (msg->what) { + switch (message->what) { case M_NEW: case B_SILENT_RELAUNCH: - NewWindow(); + _NewWindow(); break; case M_WINDOW_QUITS: - SavePreferences(msg); + _SavePreferences(message); fWindowCount--; if (fWindowCount < 1) PostMessage(B_QUIT_REQUESTED); break; default: - BApplication::MessageReceived(msg); + BApplication::MessageReceived(message); } } void -TPeopleApp::RefsReceived(BMessage *message) +TPeopleApp::RefsReceived(BMessage* message) { int32 index = 0; - while (message->HasRef("refs", index)) { entry_ref ref; message->FindRef("refs", index++, &ref); - TPeopleWindow* window = FindWindow(ref); + TPeopleWindow* window = _FindWindow(ref); if (window != NULL) window->Activate(true); else { BFile file(&ref, B_READ_ONLY); if (file.InitCheck() == B_OK) - NewWindow(&ref); + _NewWindow(&ref); } } } void -TPeopleApp::ReadyToRun(void) +TPeopleApp::ReadyToRun() { if (fWindowCount < 1) - NewWindow(); + _NewWindow(); } +// #pragma mark - + + TPeopleWindow* -TPeopleApp::NewWindow(entry_ref *ref) +TPeopleApp::_NewWindow(entry_ref* ref) { - TPeopleWindow *window; + TPeopleWindow* window = new TPeopleWindow(fPosition, + B_TRANSLATE("New person"), kNameAttribute, + kCategoryAttribute, ref); + + _AddAttributes(window); - window = new TPeopleWindow(fPosition, B_TRANSLATE("New person"), ref); window->Show(); - fWindowCount++; - fPosition.OffsetBy(20, 20); - if (fPosition.bottom > BScreen(B_MAIN_SCREEN_ID).Frame().bottom) + fWindowCount++; + + // Offset the position for the next window which will be opened and + // reset it if it would open outside the screen bounds. + fPosition.OffsetBy(20, 20); + BScreen screen(window); + if (fPosition.bottom > screen.Frame().bottom) fPosition.OffsetTo(fPosition.left, TITLE_BAR_HEIGHT); - if (fPosition.right > BScreen(B_MAIN_SCREEN_ID).Frame().right) + if (fPosition.right > screen.Frame().right) fPosition.OffsetTo(6, fPosition.top); return window; } -TPeopleWindow* -TPeopleApp::FindWindow(entry_ref ref) +void +TPeopleApp::_AddAttributes(TPeopleWindow* window) const { - TPeopleWindow* window; - int32 index = 0; + int32 count = fAttributes.CountItems(); + for (int32 i = 0; i < count; i++) { + Attribute* attribute = fAttributes.ItemAt(i); + const char* label = attribute->name; + if (attribute->attribute == kNameAttribute) + label = B_TRANSLATE("Name"); - while ((window = (TPeopleWindow *)WindowAt(index++))) { - if (window->FindView("PeopleView") != NULL && window->fRef && *window->fRef == ref) - return window; + window->AddAttribute(label, attribute->attribute); + } +} + + +TPeopleWindow* +TPeopleApp::_FindWindow(const entry_ref& ref) const +{ + for (int32 i = 0; BWindow* window = WindowAt(i); i++) { + TPeopleWindow* personWindow = dynamic_cast(window); + if (personWindow == NULL) + continue; + if (personWindow->RefersPersonFile(ref)) + return personWindow; } return NULL; } void -TPeopleApp::SavePreferences(BMessage* message) +TPeopleApp::_SavePreferences(BMessage* message) const { BRect frame; if (message->FindRect("frame", &frame) != B_OK) @@ -276,7 +339,7 @@ TPeopleApp::SavePreferences(BMessage* message) BPoint leftTop = frame.LeftTop(); - if (fPrefs) { + if (fPrefs != NULL) { fPrefs->Seek(0, 0); fPrefs->Write(&leftTop, sizeof(BPoint)); } diff --git a/src/apps/people/PeopleApp.h b/src/apps/people/PeopleApp.h index c5502c1d6b..204125031c 100644 --- a/src/apps/people/PeopleApp.h +++ b/src/apps/people/PeopleApp.h @@ -1,51 +1,39 @@ -//-------------------------------------------------------------------- -// -// PeopleApp.h -// -// 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. -*/ - -#ifndef PEOPLEAPP_H -#define PEOPLEAPP_H + * Copyright 2005-2010, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Robert Polic + * Stephan Aßmus + * + * Copyright 1999, Be Incorporated. All Rights Reserved. + * This file may be used under the terms of the Be Sample Code License. + */ +#ifndef PEOPLE_APP_H +#define PEOPLE_APP_H #include - -class BFile; +#include +#include #define B_PERSON_MIMETYPE "application/x-person" #define APP_SIG "application/x-vnd.Be-PEPL" -struct people_field { - const char* attribute; - int32 width; - const char* name; -}; -extern people_field gFields[]; -enum messages{ - M_NEW = 128, M_SAVE, M_SAVE_AS, M_REVERT, - M_UNDO, M_SELECT, M_GROUP_MENU, M_WINDOW_QUITS -}; +class BFile; -enum fields { - F_NAME = 0, F_NICKNAME, F_COMPANY, F_ADDRESS, - F_CITY, F_STATE, F_ZIP, F_COUNTRY, F_HPHONE, - F_WPHONE, F_FAX, F_EMAIL, F_URL, F_GROUP, F_END +enum { + M_NEW = 'newp', + M_SAVE_AS = 'svas', + M_WINDOW_QUITS = 'wndq' }; class TPeopleWindow; -//==================================================================== - class TPeopleApp : public BApplication { - public: +public: TPeopleApp(); virtual ~TPeopleApp(); @@ -54,17 +42,26 @@ class TPeopleApp : public BApplication { virtual void MessageReceived(BMessage*); virtual void RefsReceived(BMessage*); virtual void ReadyToRun(); - TPeopleWindow* FindWindow(entry_ref); - TPeopleWindow* NewWindow(entry_ref* = NULL); +private: + TPeopleWindow* _FindWindow(const entry_ref&) const; + TPeopleWindow* _NewWindow(entry_ref* = NULL); + void _AddAttributes(TPeopleWindow* window) const; + void _SavePreferences(BMessage* message) const; + +private: BFile* fPrefs; - - private: - void SavePreferences(BMessage* message); - uint32 fWindowCount; BRect fPosition; + + struct Attribute { + BString attribute; + int32 width; + BString name; + }; + + BObjectList fAttributes; }; -#endif /* PEOPLEAPP_H */ +#endif // PEOPLE_APP_H diff --git a/src/apps/people/PeopleView.cpp b/src/apps/people/PeopleView.cpp index a13989a909..df97a4f0bf 100644 --- a/src/apps/people/PeopleView.cpp +++ b/src/apps/people/PeopleView.cpp @@ -1,14 +1,15 @@ -//-------------------------------------------------------------------- -// -// 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. -*/ + * Copyright 2010, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Robert Polic + * Stephan Aßmus + * + * Copyright 1999, Be Incorporated. All Rights Reserved. + * This file may be used under the terms of the Be Sample Code License. + */ + #include "PeopleView.h" @@ -29,88 +30,77 @@ #include #include -#include "TTextControl.h" +#include "AttributeTextControl.h" #undef B_TRANSLATE_CONTEXT #define B_TRANSLATE_CONTEXT "People" -TPeopleView::TPeopleView(const char* name, entry_ref *ref) +TPeopleView::TPeopleView(const char* name, const char* categoryAttribute, + const entry_ref *ref) : - BGridView() + BGridView(), + fControls(20, false), + fCategoryAttribute(categoryAttribute) { SetName(name); if (ref) fFile = new BFile(ref, O_RDWR); else fFile = NULL; + + float spacing = be_control_look->DefaultItemSpacing(); + GridLayout()->SetInsets(spacing, spacing, spacing, spacing); } -TPeopleView::~TPeopleView(void) +TPeopleView::~TPeopleView() { delete fFile; } void -TPeopleView::AttachedToWindow(void) +TPeopleView::AddAttribute(const char* label, const char* attribute) { + // TODO: We could check if this attribute has already been added. + + AttributeTextControl* control = new AttributeTextControl(label, attribute); + fControls.AddItem(control); + BGridLayout* layout = GridLayout(); + int32 row = layout->CountRows(); - int32 row = 0; - for (int32 i = 0; gFields[i].attribute; i++, row++) { - const char *name = gFields[i].name; + if (fCategoryAttribute == attribute) { + // Special case the category attribute. The Group popup field will + // be added as the label instead. + fGroups = new BPopUpMenu(label); + fGroups->SetRadioMode(false); + BuildGroupMenu(); - if (i == F_NAME) - name = B_TRANSLATE("Name"); + BMenuField* field = new BMenuField("", "", fGroups); + field->SetEnabled(true); + layout->AddView(field, 0, row); - char *text = NULL; - attr_info info; - if (fFile && fFile->GetAttrInfo(gFields[i].attribute, &info) == B_OK) { - text = (char *)calloc(info.size, 1); - fFile->ReadAttr(gFields[i].attribute, B_STRING_TYPE, - 0, text, info.size); - } - - fField[i] = new TTextControl(name, text); - free(text); - - int32 labelColumn = 0; - int32 textViewColumn = 1; - int32 textViewWidth = 3; - if (i == F_STATE) - textViewWidth = 1; - else if (i == F_ZIP) { - row--; - labelColumn = 2; - textViewColumn = 3; - textViewWidth = 1; - } - - if (i != F_GROUP) { - layout->AddItem(fField[i]->CreateLabelLayoutItem(), - labelColumn, row, 1, 1); - layout->AddItem(fField[i]->CreateTextViewLayoutItem(), - textViewColumn, row, textViewWidth, 1); - } else { - fField[i]->SetLabel(""); - layout->AddView(fField[i], textViewColumn, row, textViewWidth, 1); - } + control->SetLabel(""); + layout->AddView(control, 1, row); + } else { + layout->AddItem(control->CreateLabelLayoutItem(), 0, row); + layout->AddItem(control->CreateTextViewLayoutItem(), 1, row); } - fGroups = new BPopUpMenu(gFields[F_GROUP].name); - fGroups->SetRadioMode(false); - BMenuField *field = new BMenuField("", "", fGroups); - field->SetEnabled(true); - layout->AddView(field, 0, --row); + SetAttribute(attribute, true); +} - float spacing = be_control_look->DefaultItemSpacing(); - layout->SetSpacing(spacing, spacing); - // TODO: remove this after #5614 is fixed - layout->SetInsets(spacing, spacing, spacing, spacing); - fField[F_NAME]->MakeFocus(); + +void +TPeopleView::MakeFocus(bool focus) +{ + if (focus && fControls.CountItems() > 0) + fControls.ItemAt(0)->MakeFocus(); + else + BView::MakeFocus(focus); } @@ -123,25 +113,34 @@ TPeopleView::MessageReceived(BMessage* msg) break; case M_REVERT: - for (int32 loop = 0; loop < F_END; loop++) - fField[loop]->Revert(); + for (int32 i = fControls.CountItems() - 1; i >= 0; i--) + fControls.ItemAt(i)->Revert(); break; case M_SELECT: - for (int32 loop = 0; loop < F_END; loop++) { - BTextView* text = fField[loop]->TextView(); + for (int32 i = fControls.CountItems() - 1; i >= 0; i--) { + BTextView* text = fControls.ItemAt(i)->TextView(); if (text->IsFocus()) { text->Select(0, text->TextLength()); break; } } - break; + break; + + case M_GROUP_MENU: + { + const char* name = NULL; + if (msg->FindString("group", &name) == B_OK) + SetAttribute(fCategoryAttribute, name, false); + break; + } + } } void -TPeopleView::BuildGroupMenu(void) +TPeopleView::BuildGroupMenu() { BMenuItem* item; while ((item = fGroups->ItemAt(0)) != NULL) { @@ -149,7 +148,6 @@ TPeopleView::BuildGroupMenu(void) delete item; } - const char *groupAttribute = gFields[F_GROUP].attribute; int32 count = 0; BVolumeRoster volumeRoster; @@ -159,7 +157,7 @@ TPeopleView::BuildGroupMenu(void) query.SetVolume(&volume); char buffer[256]; - sprintf(buffer, "%s=*", groupAttribute); + snprintf(buffer, sizeof(buffer), "%s=*", fCategoryAttribute.String()); query.SetPredicate(buffer); query.Fetch(); @@ -169,13 +167,15 @@ TPeopleView::BuildGroupMenu(void) attr_info info; if (file.InitCheck() == B_OK - && file.GetAttrInfo(groupAttribute, &info) == B_OK + && file.GetAttrInfo(fCategoryAttribute, &info) == B_OK && info.size > 1) { if (info.size > sizeof(buffer)) info.size = sizeof(buffer); - if (file.ReadAttr(groupAttribute, B_STRING_TYPE, 0, buffer, info.size) < B_OK) + if (file.ReadAttr(fCategoryAttribute.String(), B_STRING_TYPE, + 0, buffer, info.size) < 0) { continue; + } const char *text = buffer; while (true) { @@ -207,39 +207,19 @@ TPeopleView::BuildGroupMenu(void) } } - if (!count) { + if (count == 0) { fGroups->AddItem(item = new BMenuItem( B_TRANSLATE_WITH_CONTEXT("none", "Groups list"), new BMessage(M_GROUP_MENU))); item->SetEnabled(false); } -} - -bool -TPeopleView::CheckSave(void) -{ - for (int32 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(); - - return NULL; + fGroups->SetTargetForItems(this); } void -TPeopleView::NewFile(entry_ref *ref) +TPeopleView::CreateFile(const entry_ref* ref) { delete fFile; fFile = new BFile(ref, B_READ_WRITE); @@ -247,68 +227,107 @@ TPeopleView::NewFile(entry_ref *ref) } -void -TPeopleView::Save(void) +bool +TPeopleView::IsSaved() const { - for (int32 i = 0; gFields[i].attribute; i++) { - const char *text = fField[i]->Text(); - fFile->WriteAttr(gFields[i].attribute, B_STRING_TYPE, 0, text, strlen(text) + 1); - fField[i]->Update(); + for (int32 i = fControls.CountItems() - 1; i >= 0; i--) { + if (fControls.ItemAt(i)->HasChanged()) + return false; } + + return true; } void -TPeopleView::SetField(int32 index, bool update) +TPeopleView::Save() { - char *text = NULL; - attr_info info; - if (fFile && fFile->GetAttrInfo(gFields[index].attribute, &info) == B_OK) { - text = (char *)calloc(info.size, 1); - fFile->ReadAttr(gFields[index].attribute, B_STRING_TYPE, 0, text, - info.size); + int32 count = fControls.CountItems(); + for (int32 i = 0; i < count; i++) { + AttributeTextControl* control = fControls.ItemAt(i); + const char* value = control->Text(); + fFile->WriteAttr(control->Attribute().String(), B_STRING_TYPE, 0, + value, strlen(value) + 1); + control->Update(); } +} - SetField(index, text, update); + +const char* +TPeopleView::AttributeValue(const char* attribute) const +{ + for (int32 i = fControls.CountItems() - 1; i >= 0; i--) { + if (fControls.ItemAt(i)->Attribute() == attribute) + return fControls.ItemAt(i)->Text(); + } - free(text); + return ""; } void -TPeopleView::SetField(int32 index, char *data, bool update) +TPeopleView::SetAttribute(const char* attribute, bool update) { - Window()->Lock(); + char* value = NULL; + attr_info info; + if (fFile != NULL && fFile->GetAttrInfo(attribute, &info) == B_OK) { + value = (char*)calloc(info.size, 1); + fFile->ReadAttr(attribute, B_STRING_TYPE, 0, value, info.size); + } + + SetAttribute(attribute, value, update); + + free(value); +} + + +void +TPeopleView::SetAttribute(const char* attribute, const char* value, + bool update) +{ + if (!LockLooper()) + return; + + AttributeTextControl* control = NULL; + for (int32 i = fControls.CountItems() - 1; i >= 0; i--) { + if (fControls.ItemAt(i)->Attribute() == attribute) { + control = fControls.ItemAt(i); + break; + } + } + + if (control == NULL) + return; if (update) { - fField[index]->SetText(data); - fField[index]->Update(); + control->SetText(value); + control->Update(); } else { - BTextView* text = fField[index]->TextView(); + BTextView* text = control->TextView(); int32 start, end; text->GetSelection(&start, &end); if (start != end) { text->Delete(); - text->Insert(data); + text->Insert(value); } else if ((end = text->TextLength())) { text->Select(end, end); text->Insert(","); - text->Insert(data); + text->Insert(value); text->Select(text->TextLength(), text->TextLength()); } else - fField[index]->SetText(data); + control->SetText(value); } - Window()->Unlock(); + UnlockLooper(); } bool -TPeopleView::TextSelected(void) +TPeopleView::IsTextSelected() const { - for (int32 loop = 0; loop < F_END; loop++) { - BTextView* text = fField[loop]->TextView(); + for (int32 i = fControls.CountItems() - 1; i >= 0; i--) { + BTextView* text = fControls.ItemAt(i)->TextView(); int32 start, end; text->GetSelection(&start, &end); diff --git a/src/apps/people/PeopleView.h b/src/apps/people/PeopleView.h index 8d295dbb8c..47e8bffa50 100644 --- a/src/apps/people/PeopleView.h +++ b/src/apps/people/PeopleView.h @@ -1,48 +1,69 @@ -//-------------------------------------------------------------------- -// -// PeopleView.h -// -// 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. -*/ + * Copyright 2010, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Robert Polic + * Stephan Aßmus + * + * Copyright 1999, Be Incorporated. All Rights Reserved. + * This file may be used under the terms of the Be Sample Code License. + */ +#ifndef PEOPLE_VIEW_H +#define PEOPLE_VIEW_H -#ifndef PEOPLEVIEW_H -#define PEOPLEVIEW_H - -#include "PeopleApp.h" #include +#include +#include +class AttributeTextControl; +class BFile; class BPopUpMenu; -class TTextControl; + +enum { + M_SAVE = 'save', + M_REVERT = 'rvrt', + M_SELECT = 'slct', + M_GROUP_MENU = 'grmn', +}; class TPeopleView : public BGridView { - public: - TPeopleView(const char* name, entry_ref* ref); - ~TPeopleView(void); +public: + TPeopleView(const char* name, + const char* categoryAttribute, + const entry_ref* ref); + virtual ~TPeopleView(); - virtual void AttachedToWindow(void); - virtual void MessageReceived(BMessage*); - void BuildGroupMenu(void); - bool CheckSave(void); - const char* GetField(int32); - void NewFile(entry_ref*); - void Save(void); - void SetField(int32, bool); - void SetField(int32, char*, bool); - bool TextSelected(void); + virtual void MakeFocus(bool focus = true); + virtual void MessageReceived(BMessage* message); - private: - BFile *fFile; - BPopUpMenu *fGroups; - TTextControl *fField[F_END]; + void AddAttribute(const char* label, + const char* attribute); + void BuildGroupMenu(); + + void CreateFile(const entry_ref* ref); + + bool IsSaved() const; + void Save(); + + const char* AttributeValue(const char* attribute) const; + void SetAttribute(const char* attribute, bool update); + void SetAttribute(const char* attribute, + const char* value, bool update); + + bool IsTextSelected() const; + +private: + BFile* fFile; + BPopUpMenu* fGroups; + typedef BObjectList AttributeList; + AttributeList fControls; + + BString fCategoryAttribute; }; -#endif /* PEOPLEVIEW_H */ +#endif // PEOPLE_VIEW_H diff --git a/src/apps/people/PeopleWindow.cpp b/src/apps/people/PeopleWindow.cpp index f1831d9594..03cab2e578 100644 --- a/src/apps/people/PeopleWindow.cpp +++ b/src/apps/people/PeopleWindow.cpp @@ -1,14 +1,14 @@ -//-------------------------------------------------------------------- -// -// PeopleWindow.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. -*/ + * Copyright 2005-2010, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Robert Polic + * Stephan Aßmus + * + * Copyright 1999, Be Incorporated. All Rights Reserved. + * This file may be used under the terms of the Be Sample Code License. + */ #include "PeopleWindow.h" @@ -41,11 +41,14 @@ #define B_TRANSLATE_CONTEXT "People" -TPeopleWindow::TPeopleWindow(BRect frame, const char *title, entry_ref *ref) +TPeopleWindow::TPeopleWindow(BRect frame, const char* title, + const char* nameAttribute, const char* categoryAttribute, + const entry_ref* ref) : BWindow(frame, title, B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS), - fPanel(NULL) + fPanel(NULL), + fNameAttribute(nameAttribute) { BMenu* menu; BMenuItem* item; @@ -55,7 +58,7 @@ TPeopleWindow::TPeopleWindow(BRect frame, const char *title, entry_ref *ref) menu->AddItem(item = new BMenuItem( B_TRANSLATE("New person" B_UTF8_ELLIPSIS), new BMessage(M_NEW), 'N')); - item->SetTarget(NULL, be_app); + item->SetTarget(be_app); menu->AddItem(new BMenuItem(B_TRANSLATE("Close"), new BMessage(B_QUIT_REQUESTED), 'W')); menu->AddSeparatorItem(); @@ -71,66 +74,59 @@ TPeopleWindow::TPeopleWindow(BRect frame, const char *title, entry_ref *ref) menu->AddSeparatorItem(); item = new BMenuItem(B_TRANSLATE("Quit"), new BMessage(B_QUIT_REQUESTED), 'Q'); - item->SetTarget(NULL, be_app); + item->SetTarget(be_app); menu->AddItem(item); menuBar->AddItem(menu); menu = new BMenu(B_TRANSLATE("Edit")); menu->AddItem(fUndo = new BMenuItem(B_TRANSLATE("Undo"), new BMessage(B_UNDO), 'Z')); - fUndo->SetTarget(NULL, this); fUndo->SetEnabled(false); menu->AddSeparatorItem(); menu->AddItem(fCut = new BMenuItem(B_TRANSLATE("Cut"), new BMessage(B_CUT), 'X')); - fCut->SetTarget(NULL, this); menu->AddItem(fCopy = new BMenuItem(B_TRANSLATE("Copy"), new BMessage(B_COPY), 'C')); - fCopy->SetTarget(NULL, this); menu->AddItem(fPaste = new BMenuItem(B_TRANSLATE("Paste"), new BMessage(B_PASTE), 'V')); - fPaste->SetTarget(NULL, this); - menu->AddItem(item = new BMenuItem(B_TRANSLATE("Select all"), - new BMessage(M_SELECT), 'A')); - item->SetTarget(NULL, this); + BMenuItem* selectAllItem = new BMenuItem(B_TRANSLATE("Select all"), + new BMessage(M_SELECT), 'A'); + menu->AddItem(selectAllItem); menuBar->AddItem(menu); - if (ref) { - fRef = new entry_ref(*ref); + if (ref != NULL) { SetTitle(ref->name); - WatchChanges(true); + _SetToRef(new entry_ref(*ref)); } else - fRef = NULL; + _SetToRef(NULL); - fView = new TPeopleView("PeopleView", fRef); + fView = new TPeopleView("PeopleView", categoryAttribute, fRef); BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .SetInsets(0, 0, 0, 0) .Add(menuBar) .Add(fView); + + fRevert->SetTarget(fView); + selectAllItem->SetTarget(fView); } -TPeopleWindow::~TPeopleWindow(void) +TPeopleWindow::~TPeopleWindow() { - if (fRef) - WatchChanges(false); - - delete fRef; + _SetToRef(NULL); } void -TPeopleWindow::MenusBeginning(void) +TPeopleWindow::MenusBeginning() { - bool enabled; - bool isRedo; - - enabled = fView->CheckSave(); + bool enabled = !fView->IsSaved(); fSave->SetEnabled(enabled); fRevert->SetEnabled(enabled); - undo_state state = ((BTextView *)CurrentFocus())->UndoState(&isRedo); + bool isRedo = false; + undo_state state = ((BTextView*)CurrentFocus())->UndoState(&isRedo); fUndo->SetEnabled(state != B_UNDO_UNAVAILABLE); if (isRedo) @@ -138,7 +134,7 @@ TPeopleWindow::MenusBeginning(void) else fUndo->SetLabel(B_TRANSLATE("Undo")); - enabled = fView->TextSelected(); + enabled = fView->IsTextSelected(); fCut->SetEnabled(enabled); fCopy->SetEnabled(enabled); @@ -154,7 +150,6 @@ void TPeopleWindow::MessageReceived(BMessage* msg) { char str[256]; - entry_ref dir; BDirectory directory; BEntry entry; BFile file; @@ -166,6 +161,7 @@ TPeopleWindow::MessageReceived(BMessage* msg) SaveAs(); break; } + // supposed to fall through case M_REVERT: case M_SELECT: fView->MessageReceived(msg); @@ -175,16 +171,11 @@ TPeopleWindow::MessageReceived(BMessage* msg) SaveAs(); break; - case M_GROUP_MENU: - { - char *name = NULL; - msg->FindString("group", (const char **)&name); - fView->SetField(F_GROUP, name, FALSE); - break; - } case B_SAVE_REQUESTED: - if (msg->FindRef("directory", &dir) == B_NO_ERROR) { - const char *name = NULL; + { + entry_ref dir; + if (msg->FindRef("directory", &dir) == B_OK) { + const char* name = NULL; msg->FindString("name", &name); directory.SetTo(&dir); if (directory.InitCheck() == B_NO_ERROR) { @@ -196,14 +187,9 @@ TPeopleWindow::MessageReceived(BMessage* msg) directory.FindEntry(name, &entry); entry.GetRef(&dir); - if (fRef) { - WatchChanges(false); - delete fRef; - } - fRef = new entry_ref(dir); - WatchChanges(true); + _SetToRef(new entry_ref(dir)); SetTitle(fRef->name); - fView->NewFile(fRef); + fView->CreateFile(fRef); } else { sprintf(str, B_TRANSLATE("Could not create %s."), name); @@ -212,18 +198,15 @@ TPeopleWindow::MessageReceived(BMessage* msg) } } break; - + } + case B_NODE_MONITOR: { int32 opcode; if (msg->FindInt32("opcode", &opcode) == B_OK) { switch (opcode) { case B_ENTRY_REMOVED: - // We lost our file. Close the window by quiting its - // looper. - delete fRef; - fRef = NULL; - + // We lost our file. Close the window. PostMessage(B_QUIT_REQUESTED); break; @@ -244,7 +227,6 @@ TPeopleWindow::MessageReceived(BMessage* msg) delete fRef; fRef = new entry_ref(device, directory, name.String()); - // And our window title. SetTitle(name); @@ -255,11 +237,8 @@ TPeopleWindow::MessageReceived(BMessage* msg) &volume); BPath folder(fRef); folder.GetParent(&folder); - if (folder == trash) { - delete fRef; - fRef = NULL; + if (folder == trash) PostMessage(B_QUIT_REQUESTED); - } break; } @@ -268,13 +247,8 @@ TPeopleWindow::MessageReceived(BMessage* msg) { // An attribute was updated. BString attr; - if (msg->FindString("attr", &attr) == B_OK) { - for (int32 i = 0; gFields[i].attribute; i++) { - if (attr == gFields[i].attribute) { - fView->SetField(i, true); - } - } - } + if (msg->FindString("attr", &attr) == B_OK) + fView->SetAttribute(attr.String(), true); break; } } @@ -289,11 +263,11 @@ TPeopleWindow::MessageReceived(BMessage* msg) bool -TPeopleWindow::QuitRequested(void) +TPeopleWindow::QuitRequested() { status_t result; - if (fView->CheckSave()) { + if (!fView->IsSaved()) { result = (new BAlert("", B_TRANSLATE("Save changes before quitting?"), B_TRANSLATE("Cancel"), B_TRANSLATE("Quit"), B_TRANSLATE("Save")))->Go(); @@ -322,9 +296,68 @@ TPeopleWindow::QuitRequested(void) void -TPeopleWindow::DefaultName(char *name) +TPeopleWindow::Show() { - strncpy(name, fView->GetField(F_NAME), B_FILE_NAME_LENGTH); + fView->MakeFocus(); + BWindow::Show(); +} + + +void +TPeopleWindow::AddAttribute(const char* label, const char* attribute) +{ + fView->AddAttribute(label, attribute); +} + + +void +TPeopleWindow::SaveAs() +{ + char name[B_FILE_NAME_LENGTH]; + _GetDefaultFileName(name); + + if (fPanel == NULL) { + BMessenger target(this); + fPanel = new BFilePanel(B_SAVE_PANEL, &target); + + BPath path; + find_directory(B_USER_DIRECTORY, &path, true); + + BDirectory dir; + dir.SetTo(path.Path()); + + BEntry entry; + if (dir.FindEntry("people", &entry) == B_OK + || (dir.CreateDirectory("people", &dir) == B_OK + && dir.GetEntry(&entry) == B_OK)) { + fPanel->SetPanelDirectory(&entry); + } + } + + if (fPanel->Window()->Lock()) { + fPanel->SetSaveText(name); + if (fPanel->Window()->IsHidden()) + fPanel->Window()->Show(); + else + fPanel->Window()->Activate(); + fPanel->Window()->Unlock(); + } +} + + +bool +TPeopleWindow::RefersPersonFile(const entry_ref& ref) const +{ + if (fRef == NULL) + return false; + return *fRef == ref; +} + + +void +TPeopleWindow::_GetDefaultFileName(char* name) +{ + strncpy(name, fView->AttributeValue(fNameAttribute), B_FILE_NAME_LENGTH); while (*name) { if (*name == '/') *name = '-'; @@ -334,52 +367,21 @@ TPeopleWindow::DefaultName(char *name) void -TPeopleWindow::SetField(int32 index, char *text) +TPeopleWindow::_SetToRef(entry_ref* ref) { - fView->SetField(index, text, true); + if (fRef != NULL) { + _WatchChanges(false); + delete fRef; + } + + fRef = ref; + + _WatchChanges(true); } void -TPeopleWindow::SaveAs(void) -{ - char name[B_FILE_NAME_LENGTH]; - BDirectory dir; - BEntry entry; - BMessenger window(this); - BPath path; - - DefaultName(name); - if (!fPanel) { - fPanel = new BFilePanel(B_SAVE_PANEL, &window); - fPanel->SetSaveText(name); - find_directory(B_USER_DIRECTORY, &path, true); - dir.SetTo(path.Path()); - if (dir.FindEntry("people", &entry) == B_NO_ERROR) - fPanel->SetPanelDirectory(&entry); - else if (dir.CreateDirectory("people", &dir) == B_NO_ERROR) { - dir.GetEntry(&entry); - fPanel->SetPanelDirectory(&entry); - } - } - else if (fPanel->Window()->Lock()) { - if (!fPanel->Window()->IsHidden()) - fPanel->Window()->Activate(); - else - fPanel->SetSaveText(name); - fPanel->Window()->Unlock(); - } - - if (fPanel->Window()->Lock()) { - if (fPanel->Window()->IsHidden()) - fPanel->Window()->Show(); - fPanel->Window()->Unlock(); - } -} - - -void -TPeopleWindow::WatchChanges(bool enable) +TPeopleWindow::_WatchChanges(bool enable) { if (fRef == NULL) return; diff --git a/src/apps/people/PeopleWindow.h b/src/apps/people/PeopleWindow.h index 4f3132c724..48fd202ffd 100644 --- a/src/apps/people/PeopleWindow.h +++ b/src/apps/people/PeopleWindow.h @@ -1,56 +1,71 @@ -//-------------------------------------------------------------------- -// -// PeopleWindow.h -// -// 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. -*/ + * Copyright 2010, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Authors: + * Robert Polic + * + * Copyright 1999, Be Incorporated. All Rights Reserved. + * This file may be used under the terms of the Be Sample Code License. + */ +#ifndef PEOPLE_WINDOW_H +#define PEOPLE_WINDOW_H + + +#include +#include -#ifndef PEOPLEWINDOW_H -#define PEOPLEWINDOW_H #define TITLE_BAR_HEIGHT 25 #define WIND_WIDTH 321 #define WIND_HEIGHT 340 + class TPeopleView; class BFilePanel; class BMenuItem; -#include -//==================================================================== class TPeopleWindow : public BWindow { - -private: - - void WatchChanges(bool); - - BFilePanel *fPanel; - BMenuItem *fCopy; - BMenuItem *fCut; - BMenuItem *fPaste; - BMenuItem *fRevert; - BMenuItem *fSave; - BMenuItem *fUndo; - TPeopleView *fView; - public: - entry_ref *fRef; + TPeopleWindow(BRect frame, const char* title, + const char* nameAttribute, + const char* categoryAttribute, + const entry_ref* ref); + virtual ~TPeopleWindow(); - TPeopleWindow(BRect, const char*, entry_ref*); - ~TPeopleWindow(void); - virtual void MenusBeginning(void); - virtual void MessageReceived(BMessage*); - virtual bool QuitRequested(void); - void DefaultName(char*); - void SetField(int32, char*); - void SaveAs(void); + virtual void MenusBeginning(); + virtual void MessageReceived(BMessage* message); + virtual bool QuitRequested(); + virtual void Show(); + + void AddAttribute(const char* label, + const char* attribute); + + void SaveAs(); + + bool RefersPersonFile(const entry_ref& ref) const; + +private: + void _GetDefaultFileName(char* name); + void _SetToRef(entry_ref* ref); + void _WatchChanges(bool doIt); + +private: + entry_ref* fRef; + + BFilePanel* fPanel; + BMenuItem* fCopy; + BMenuItem* fCut; + BMenuItem* fPaste; + BMenuItem* fRevert; + BMenuItem* fSave; + BMenuItem* fUndo; + TPeopleView* fView; + + BString fNameAttribute; }; -#endif /* PEOPLEWINDOW_H */ + +#endif // PEOPLE_WINDOW_H diff --git a/src/apps/people/TTextControl.cpp b/src/apps/people/TTextControl.cpp deleted file mode 100644 index 643a1a42dd..0000000000 --- a/src/apps/people/TTextControl.cpp +++ /dev/null @@ -1,66 +0,0 @@ -//-------------------------------------------------------------------- -// -// TTextControl.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 "TTextControl.h" - - -TTextControl::TTextControl(const char *label, const char *text) - : - BTextControl(NULL, text, NULL) -{ - - if (label && label[0]) - SetLabel(BString(label).Append(":")); - SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); - fOriginal = text; -} - - -TTextControl::~TTextControl() -{ -} - - -void -TTextControl::AttachedToWindow() -{ - BTextControl::AttachedToWindow(); - - BTextView* text = (BTextView *)ChildAt(0); - text->SetMaxBytes(255); -} - - -bool -TTextControl::Changed() -{ - return fOriginal != Text(); -} - - -void -TTextControl::Revert(void) -{ - if (Changed()) - SetText(fOriginal); -} - - -void -TTextControl::Update(void) -{ - fOriginal = Text(); -} diff --git a/src/apps/people/TTextControl.h b/src/apps/people/TTextControl.h deleted file mode 100644 index 70379be439..0000000000 --- a/src/apps/people/TTextControl.h +++ /dev/null @@ -1,34 +0,0 @@ -//-------------------------------------------------------------------- -// -// TTextControl.h -// -// 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. -*/ - -#ifndef TEXTCONTROL_H -#define TEXTCONTROL_H - -#include -#include - -class TTextControl : public BTextControl { - public: - TTextControl(const char* label, const char* text); - virtual ~TTextControl(); - - virtual void AttachedToWindow(); - - bool Changed(); - void Revert(); - void Update(); - - private: - BString fOriginal; -}; - -#endif /* TEXTCONTROL_H */ diff --git a/src/apps/people/main.cpp b/src/apps/people/main.cpp index fe50b822bb..9b24954d97 100644 --- a/src/apps/people/main.cpp +++ b/src/apps/people/main.cpp @@ -1,24 +1,19 @@ -//-------------------------------------------------------------------- -// -// main.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. -*/ + * Copyright 1999, Be Incorporated. All Rights Reserved. + * This file may be used under the terms of the Be Sample Code License. + * + * Authors: + * Robert Polic + */ + #include "PeopleApp.h" -int main(void) + +int +main(int, char**) { - TPeopleApp *app; - - app = new TPeopleApp(); - app->Run(); - - delete app; + TPeopleApp app; + app.Run(); return B_NO_ERROR; }