Reimplemented how People works. The previously hard-coded attribute list
is now only a fallback attribute list which is install in case the Person MIME type has no attributes at all. Otherwise the GUI is completely driven by the current Person attributes, as configured (and sorted) by FileTypes. This has been on my mental TODO list since years. Finally one can add a "Cell phone" attribute in Filetypes and actually see and edit it in People. Or a birth day attribute. If I had read the previous code correctly, it was only due to a bug that People did not remove those any attributes on every launch. I've tested this quite a bit, but it wouldn't hurt to test it some more. The only "regression" I am aware of is that State and Zip code are not in one line anymore. Perhaps this feature could be reintroduced by looking at the display width and if two attributes are short, put them in one line... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40381 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -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 <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <Font.h>
|
||||||
|
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
@@ -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 <String.h>
|
||||||
|
#include <TextControl.h>
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
SubDir HAIKU_TOP src apps people ;
|
SubDir HAIKU_TOP src apps people ;
|
||||||
|
|
||||||
|
UsePrivateHeaders shared ;
|
||||||
|
|
||||||
Application People : main.cpp
|
Application People : main.cpp
|
||||||
|
AttributeTextControl.cpp
|
||||||
PeopleApp.cpp
|
PeopleApp.cpp
|
||||||
PeopleView.cpp
|
PeopleView.cpp
|
||||||
PeopleWindow.cpp
|
PeopleWindow.cpp
|
||||||
TTextControl.cpp
|
|
||||||
: libbe.so libtracker.so $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS)
|
: libbe.so libtracker.so $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS)
|
||||||
: People.rdef
|
: People.rdef
|
||||||
;
|
;
|
||||||
|
|||||||
+149
-86
@@ -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.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Robert Polic
|
* Robert Polic
|
||||||
* Axel Dörfler, [email protected]
|
* Axel Dörfler, [email protected]
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
*
|
*
|
||||||
* Copyright 1999, Be Incorporated. All Rights Reserved.
|
* Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||||
* This file may be used under the terms of the Be Sample Code License.
|
* This file may be used under the terms of the Be Sample Code License.
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
|
#include <AutoDeleter.h>
|
||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
@@ -34,8 +36,18 @@
|
|||||||
#define B_TRANSLATE_CONTEXT "People"
|
#define B_TRANSLATE_CONTEXT "People"
|
||||||
|
|
||||||
|
|
||||||
struct people_field gFields[] = {
|
struct DefaultAttribute {
|
||||||
{ "META:name", 120, B_TRANSLATE("Contact name") },
|
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:nickname", 120, B_TRANSLATE("Nickname") },
|
||||||
{ "META:company", 120, B_TRANSLATE("Company") },
|
{ "META:company", 120, B_TRANSLATE("Company") },
|
||||||
{ "META:address", 120, B_TRANSLATE("Address") },
|
{ "META:address", 120, B_TRANSLATE("Address") },
|
||||||
@@ -48,16 +60,19 @@ struct people_field gFields[] = {
|
|||||||
{ "META:fax", 90, B_TRANSLATE("Fax") },
|
{ "META:fax", 90, B_TRANSLATE("Fax") },
|
||||||
{ "META:email", 120, B_TRANSLATE("E-mail") },
|
{ "META:email", 120, B_TRANSLATE("E-mail") },
|
||||||
{ "META:url", 120, B_TRANSLATE("URL") },
|
{ "META:url", 120, B_TRANSLATE("URL") },
|
||||||
{ "META:group", 120, B_TRANSLATE("Group") },
|
{ kCategoryAttribute, 120, B_TRANSLATE("Group") },
|
||||||
{ NULL, 0, NULL }
|
{ NULL, 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TPeopleApp::TPeopleApp(void)
|
TPeopleApp::TPeopleApp()
|
||||||
: BApplication(APP_SIG),
|
:
|
||||||
fWindowCount(0)
|
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();
|
BPoint pos = fPosition.LeftTop();
|
||||||
|
|
||||||
BPath path;
|
BPath path;
|
||||||
@@ -65,7 +80,7 @@ TPeopleApp::TPeopleApp(void)
|
|||||||
|
|
||||||
BDirectory dir(path.Path());
|
BDirectory dir(path.Path());
|
||||||
BEntry entry;
|
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);
|
fPrefs = new BFile(&entry, B_READ_WRITE);
|
||||||
if (fPrefs->InitCheck() == B_NO_ERROR) {
|
if (fPrefs->InitCheck() == B_NO_ERROR) {
|
||||||
fPrefs->Read(&pos, sizeof(BPoint));
|
fPrefs->Read(&pos, sizeof(BPoint));
|
||||||
@@ -74,23 +89,15 @@ TPeopleApp::TPeopleApp(void)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fPrefs = new BFile();
|
fPrefs = new BFile();
|
||||||
if (dir.CreateFile("People_data", fPrefs) != B_NO_ERROR) {
|
if (dir.CreateFile("People_data", fPrefs) != B_OK) {
|
||||||
delete fPrefs;
|
delete fPrefs;
|
||||||
fPrefs = NULL;
|
fPrefs = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create indices on all volumes
|
// Read attributes from person mime type. If it does not exist,
|
||||||
|
// or if it contains no attribute definitions, install a "clean"
|
||||||
BVolumeRoster volumeRoster;
|
// person mime type from the hard-coded default attributes.
|
||||||
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
|
|
||||||
|
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
BMimeType mime;
|
BMimeType mime;
|
||||||
@@ -99,17 +106,42 @@ TPeopleApp::TPeopleApp(void)
|
|||||||
if (mime.IsInstalled()) {
|
if (mime.IsInstalled()) {
|
||||||
BMessage info;
|
BMessage info;
|
||||||
if (mime.GetAttrInfo(&info) == B_NO_ERROR) {
|
if (mime.GetAttrInfo(&info) == B_NO_ERROR) {
|
||||||
const char *string;
|
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
while (info.FindString("attr:name", index++, &string) == B_OK) {
|
while (true) {
|
||||||
if (!strcmp(string, gFields[0].attribute)) {
|
int32 type;
|
||||||
valid = true;
|
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<Attribute> deleter(attribute);
|
||||||
|
if (info.FindString("attr:public_name", index,
|
||||||
|
&attribute->name) != B_OK) {
|
||||||
break;
|
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) {
|
if (!valid) {
|
||||||
mime.Install();
|
mime.Install();
|
||||||
@@ -121,154 +153,185 @@ TPeopleApp::TPeopleApp(void)
|
|||||||
mime.SetIcon(kPersonIcon, sizeof(kPersonIcon));
|
mime.SetIcon(kPersonIcon, sizeof(kPersonIcon));
|
||||||
mime.SetPreferredApp(APP_SIG);
|
mime.SetPreferredApp(APP_SIG);
|
||||||
|
|
||||||
// add relevant person fields to meta-mime type
|
// add default person fields to meta-mime type
|
||||||
|
|
||||||
BMessage fields;
|
BMessage fields;
|
||||||
for (int32 i = 0; gFields[i].attribute; i++) {
|
for (int32 i = 0; sDefaultAttributes[i].attribute; i++) {
|
||||||
fields.AddString("attr:public_name", gFields[i].name);
|
fields.AddString("attr:public_name", sDefaultAttributes[i].name);
|
||||||
fields.AddString("attr:name", gFields[i].attribute);
|
fields.AddString("attr:name", sDefaultAttributes[i].attribute);
|
||||||
fields.AddInt32("attr:type", B_STRING_TYPE);
|
fields.AddInt32("attr:type", B_STRING_TYPE);
|
||||||
fields.AddBool("attr:viewable", true);
|
fields.AddBool("attr:viewable", true);
|
||||||
fields.AddBool("attr:editable", 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.AddInt32("attr:alignment", B_ALIGN_LEFT);
|
||||||
fields.AddBool("attr:extra", false);
|
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);
|
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;
|
delete fPrefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
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
|
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++) {
|
for (int32 i = 1; i < argc; i++) {
|
||||||
char* arg = argv[loop];
|
BEntry entry(argv[i]);
|
||||||
|
entry_ref ref;
|
||||||
int32 index;
|
if (entry.Exists() && entry.GetRef(&ref) == B_OK)
|
||||||
for (index = 0; gFields[index].attribute; index++) {
|
message.AddRef("refs", &ref);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RefsReceived(&message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TPeopleApp::MessageReceived(BMessage *msg)
|
TPeopleApp::MessageReceived(BMessage* message)
|
||||||
{
|
{
|
||||||
switch (msg->what) {
|
switch (message->what) {
|
||||||
case M_NEW:
|
case M_NEW:
|
||||||
case B_SILENT_RELAUNCH:
|
case B_SILENT_RELAUNCH:
|
||||||
NewWindow();
|
_NewWindow();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_WINDOW_QUITS:
|
case M_WINDOW_QUITS:
|
||||||
SavePreferences(msg);
|
_SavePreferences(message);
|
||||||
fWindowCount--;
|
fWindowCount--;
|
||||||
if (fWindowCount < 1)
|
if (fWindowCount < 1)
|
||||||
PostMessage(B_QUIT_REQUESTED);
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BApplication::MessageReceived(msg);
|
BApplication::MessageReceived(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TPeopleApp::RefsReceived(BMessage *message)
|
TPeopleApp::RefsReceived(BMessage* message)
|
||||||
{
|
{
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
|
|
||||||
while (message->HasRef("refs", index)) {
|
while (message->HasRef("refs", index)) {
|
||||||
entry_ref ref;
|
entry_ref ref;
|
||||||
message->FindRef("refs", index++, &ref);
|
message->FindRef("refs", index++, &ref);
|
||||||
|
|
||||||
TPeopleWindow* window = FindWindow(ref);
|
TPeopleWindow* window = _FindWindow(ref);
|
||||||
if (window != NULL)
|
if (window != NULL)
|
||||||
window->Activate(true);
|
window->Activate(true);
|
||||||
else {
|
else {
|
||||||
BFile file(&ref, B_READ_ONLY);
|
BFile file(&ref, B_READ_ONLY);
|
||||||
if (file.InitCheck() == B_OK)
|
if (file.InitCheck() == B_OK)
|
||||||
NewWindow(&ref);
|
_NewWindow(&ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TPeopleApp::ReadyToRun(void)
|
TPeopleApp::ReadyToRun()
|
||||||
{
|
{
|
||||||
if (fWindowCount < 1)
|
if (fWindowCount < 1)
|
||||||
NewWindow();
|
_NewWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
TPeopleWindow*
|
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();
|
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);
|
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);
|
fPosition.OffsetTo(6, fPosition.top);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TPeopleWindow*
|
void
|
||||||
TPeopleApp::FindWindow(entry_ref ref)
|
TPeopleApp::_AddAttributes(TPeopleWindow* window) const
|
||||||
{
|
{
|
||||||
TPeopleWindow* window;
|
int32 count = fAttributes.CountItems();
|
||||||
int32 index = 0;
|
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++))) {
|
window->AddAttribute(label, attribute->attribute);
|
||||||
if (window->FindView("PeopleView") != NULL && window->fRef && *window->fRef == ref)
|
}
|
||||||
return window;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TPeopleWindow*
|
||||||
|
TPeopleApp::_FindWindow(const entry_ref& ref) const
|
||||||
|
{
|
||||||
|
for (int32 i = 0; BWindow* window = WindowAt(i); i++) {
|
||||||
|
TPeopleWindow* personWindow = dynamic_cast<TPeopleWindow*>(window);
|
||||||
|
if (personWindow == NULL)
|
||||||
|
continue;
|
||||||
|
if (personWindow->RefersPersonFile(ref))
|
||||||
|
return personWindow;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TPeopleApp::SavePreferences(BMessage* message)
|
TPeopleApp::_SavePreferences(BMessage* message) const
|
||||||
{
|
{
|
||||||
BRect frame;
|
BRect frame;
|
||||||
if (message->FindRect("frame", &frame) != B_OK)
|
if (message->FindRect("frame", &frame) != B_OK)
|
||||||
@@ -276,7 +339,7 @@ TPeopleApp::SavePreferences(BMessage* message)
|
|||||||
|
|
||||||
BPoint leftTop = frame.LeftTop();
|
BPoint leftTop = frame.LeftTop();
|
||||||
|
|
||||||
if (fPrefs) {
|
if (fPrefs != NULL) {
|
||||||
fPrefs->Seek(0, 0);
|
fPrefs->Seek(0, 0);
|
||||||
fPrefs->Write(&leftTop, sizeof(BPoint));
|
fPrefs->Write(&leftTop, sizeof(BPoint));
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-39
@@ -1,51 +1,39 @@
|
|||||||
//--------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PeopleApp.h
|
|
||||||
//
|
|
||||||
// Written by: Robert Polic
|
|
||||||
//
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
/*
|
/*
|
||||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
* Copyright 2005-2010, Haiku, Inc. All rights reserved.
|
||||||
This file may be used under the terms of the Be Sample Code License.
|
* Distributed under the terms of the MIT license.
|
||||||
*/
|
*
|
||||||
|
* Authors:
|
||||||
#ifndef PEOPLEAPP_H
|
* Robert Polic
|
||||||
#define PEOPLEAPP_H
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*
|
||||||
|
* 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 <Application.h>
|
#include <Application.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
class BFile;
|
#include <String.h>
|
||||||
|
|
||||||
|
|
||||||
#define B_PERSON_MIMETYPE "application/x-person"
|
#define B_PERSON_MIMETYPE "application/x-person"
|
||||||
#define APP_SIG "application/x-vnd.Be-PEPL"
|
#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{
|
class BFile;
|
||||||
M_NEW = 128, M_SAVE, M_SAVE_AS, M_REVERT,
|
|
||||||
M_UNDO, M_SELECT, M_GROUP_MENU, M_WINDOW_QUITS
|
|
||||||
};
|
|
||||||
|
|
||||||
enum fields {
|
enum {
|
||||||
F_NAME = 0, F_NICKNAME, F_COMPANY, F_ADDRESS,
|
M_NEW = 'newp',
|
||||||
F_CITY, F_STATE, F_ZIP, F_COUNTRY, F_HPHONE,
|
M_SAVE_AS = 'svas',
|
||||||
F_WPHONE, F_FAX, F_EMAIL, F_URL, F_GROUP, F_END
|
M_WINDOW_QUITS = 'wndq'
|
||||||
};
|
};
|
||||||
|
|
||||||
class TPeopleWindow;
|
class TPeopleWindow;
|
||||||
|
|
||||||
//====================================================================
|
|
||||||
|
|
||||||
class TPeopleApp : public BApplication {
|
class TPeopleApp : public BApplication {
|
||||||
public:
|
public:
|
||||||
TPeopleApp();
|
TPeopleApp();
|
||||||
virtual ~TPeopleApp();
|
virtual ~TPeopleApp();
|
||||||
|
|
||||||
@@ -54,17 +42,26 @@ class TPeopleApp : public BApplication {
|
|||||||
virtual void MessageReceived(BMessage*);
|
virtual void MessageReceived(BMessage*);
|
||||||
virtual void RefsReceived(BMessage*);
|
virtual void RefsReceived(BMessage*);
|
||||||
virtual void ReadyToRun();
|
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;
|
BFile* fPrefs;
|
||||||
|
|
||||||
private:
|
|
||||||
void SavePreferences(BMessage* message);
|
|
||||||
|
|
||||||
uint32 fWindowCount;
|
uint32 fWindowCount;
|
||||||
BRect fPosition;
|
BRect fPosition;
|
||||||
|
|
||||||
|
struct Attribute {
|
||||||
|
BString attribute;
|
||||||
|
int32 width;
|
||||||
|
BString name;
|
||||||
|
};
|
||||||
|
|
||||||
|
BObjectList<Attribute> fAttributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* PEOPLEAPP_H */
|
#endif // PEOPLE_APP_H
|
||||||
|
|
||||||
|
|||||||
+141
-122
@@ -1,14 +1,15 @@
|
|||||||
//--------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PeopleView.cpp
|
|
||||||
//
|
|
||||||
// Written by: Robert Polic
|
|
||||||
//
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
/*
|
/*
|
||||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
* Copyright 2010, Haiku, Inc. All rights reserved.
|
||||||
This file may be used under the terms of the Be Sample Code License.
|
* Distributed under the terms of the MIT license.
|
||||||
*/
|
*
|
||||||
|
* Authors:
|
||||||
|
* Robert Polic
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*
|
||||||
|
* Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||||
|
* This file may be used under the terms of the Be Sample Code License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "PeopleView.h"
|
#include "PeopleView.h"
|
||||||
|
|
||||||
@@ -29,88 +30,77 @@
|
|||||||
#include <VolumeRoster.h>
|
#include <VolumeRoster.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
#include "TTextControl.h"
|
#include "AttributeTextControl.h"
|
||||||
|
|
||||||
|
|
||||||
#undef B_TRANSLATE_CONTEXT
|
#undef B_TRANSLATE_CONTEXT
|
||||||
#define B_TRANSLATE_CONTEXT "People"
|
#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);
|
SetName(name);
|
||||||
if (ref)
|
if (ref)
|
||||||
fFile = new BFile(ref, O_RDWR);
|
fFile = new BFile(ref, O_RDWR);
|
||||||
else
|
else
|
||||||
fFile = NULL;
|
fFile = NULL;
|
||||||
|
|
||||||
|
float spacing = be_control_look->DefaultItemSpacing();
|
||||||
|
GridLayout()->SetInsets(spacing, spacing, spacing, spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TPeopleView::~TPeopleView(void)
|
TPeopleView::~TPeopleView()
|
||||||
{
|
{
|
||||||
delete fFile;
|
delete fFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
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();
|
BGridLayout* layout = GridLayout();
|
||||||
|
int32 row = layout->CountRows();
|
||||||
|
|
||||||
int32 row = 0;
|
if (fCategoryAttribute == attribute) {
|
||||||
for (int32 i = 0; gFields[i].attribute; i++, row++) {
|
// Special case the category attribute. The Group popup field will
|
||||||
const char *name = gFields[i].name;
|
// be added as the label instead.
|
||||||
|
fGroups = new BPopUpMenu(label);
|
||||||
|
fGroups->SetRadioMode(false);
|
||||||
|
BuildGroupMenu();
|
||||||
|
|
||||||
if (i == F_NAME)
|
BMenuField* field = new BMenuField("", "", fGroups);
|
||||||
name = B_TRANSLATE("Name");
|
field->SetEnabled(true);
|
||||||
|
layout->AddView(field, 0, row);
|
||||||
|
|
||||||
char *text = NULL;
|
control->SetLabel("");
|
||||||
attr_info info;
|
layout->AddView(control, 1, row);
|
||||||
if (fFile && fFile->GetAttrInfo(gFields[i].attribute, &info) == B_OK) {
|
} else {
|
||||||
text = (char *)calloc(info.size, 1);
|
layout->AddItem(control->CreateLabelLayoutItem(), 0, row);
|
||||||
fFile->ReadAttr(gFields[i].attribute, B_STRING_TYPE,
|
layout->AddItem(control->CreateTextViewLayoutItem(), 1, row);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fGroups = new BPopUpMenu(gFields[F_GROUP].name);
|
SetAttribute(attribute, true);
|
||||||
fGroups->SetRadioMode(false);
|
}
|
||||||
BMenuField *field = new BMenuField("", "", fGroups);
|
|
||||||
field->SetEnabled(true);
|
|
||||||
layout->AddView(field, 0, --row);
|
|
||||||
|
|
||||||
float spacing = be_control_look->DefaultItemSpacing();
|
|
||||||
layout->SetSpacing(spacing, spacing);
|
void
|
||||||
// TODO: remove this after #5614 is fixed
|
TPeopleView::MakeFocus(bool focus)
|
||||||
layout->SetInsets(spacing, spacing, spacing, spacing);
|
{
|
||||||
fField[F_NAME]->MakeFocus();
|
if (focus && fControls.CountItems() > 0)
|
||||||
|
fControls.ItemAt(0)->MakeFocus();
|
||||||
|
else
|
||||||
|
BView::MakeFocus(focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -123,25 +113,34 @@ TPeopleView::MessageReceived(BMessage* msg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case M_REVERT:
|
case M_REVERT:
|
||||||
for (int32 loop = 0; loop < F_END; loop++)
|
for (int32 i = fControls.CountItems() - 1; i >= 0; i--)
|
||||||
fField[loop]->Revert();
|
fControls.ItemAt(i)->Revert();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_SELECT:
|
case M_SELECT:
|
||||||
for (int32 loop = 0; loop < F_END; loop++) {
|
for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
|
||||||
BTextView* text = fField[loop]->TextView();
|
BTextView* text = fControls.ItemAt(i)->TextView();
|
||||||
if (text->IsFocus()) {
|
if (text->IsFocus()) {
|
||||||
text->Select(0, text->TextLength());
|
text->Select(0, text->TextLength());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case M_GROUP_MENU:
|
||||||
|
{
|
||||||
|
const char* name = NULL;
|
||||||
|
if (msg->FindString("group", &name) == B_OK)
|
||||||
|
SetAttribute(fCategoryAttribute, name, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TPeopleView::BuildGroupMenu(void)
|
TPeopleView::BuildGroupMenu()
|
||||||
{
|
{
|
||||||
BMenuItem* item;
|
BMenuItem* item;
|
||||||
while ((item = fGroups->ItemAt(0)) != NULL) {
|
while ((item = fGroups->ItemAt(0)) != NULL) {
|
||||||
@@ -149,7 +148,6 @@ TPeopleView::BuildGroupMenu(void)
|
|||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *groupAttribute = gFields[F_GROUP].attribute;
|
|
||||||
int32 count = 0;
|
int32 count = 0;
|
||||||
|
|
||||||
BVolumeRoster volumeRoster;
|
BVolumeRoster volumeRoster;
|
||||||
@@ -159,7 +157,7 @@ TPeopleView::BuildGroupMenu(void)
|
|||||||
query.SetVolume(&volume);
|
query.SetVolume(&volume);
|
||||||
|
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
sprintf(buffer, "%s=*", groupAttribute);
|
snprintf(buffer, sizeof(buffer), "%s=*", fCategoryAttribute.String());
|
||||||
query.SetPredicate(buffer);
|
query.SetPredicate(buffer);
|
||||||
query.Fetch();
|
query.Fetch();
|
||||||
|
|
||||||
@@ -169,13 +167,15 @@ TPeopleView::BuildGroupMenu(void)
|
|||||||
attr_info info;
|
attr_info info;
|
||||||
|
|
||||||
if (file.InitCheck() == B_OK
|
if (file.InitCheck() == B_OK
|
||||||
&& file.GetAttrInfo(groupAttribute, &info) == B_OK
|
&& file.GetAttrInfo(fCategoryAttribute, &info) == B_OK
|
||||||
&& info.size > 1) {
|
&& info.size > 1) {
|
||||||
if (info.size > sizeof(buffer))
|
if (info.size > sizeof(buffer))
|
||||||
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const char *text = buffer;
|
const char *text = buffer;
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -207,39 +207,19 @@ TPeopleView::BuildGroupMenu(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!count) {
|
if (count == 0) {
|
||||||
fGroups->AddItem(item = new BMenuItem(
|
fGroups->AddItem(item = new BMenuItem(
|
||||||
B_TRANSLATE_WITH_CONTEXT("none", "Groups list"),
|
B_TRANSLATE_WITH_CONTEXT("none", "Groups list"),
|
||||||
new BMessage(M_GROUP_MENU)));
|
new BMessage(M_GROUP_MENU)));
|
||||||
item->SetEnabled(false);
|
item->SetEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
fGroups->SetTargetForItems(this);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TPeopleView::NewFile(entry_ref *ref)
|
TPeopleView::CreateFile(const entry_ref* ref)
|
||||||
{
|
{
|
||||||
delete fFile;
|
delete fFile;
|
||||||
fFile = new BFile(ref, B_READ_WRITE);
|
fFile = new BFile(ref, B_READ_WRITE);
|
||||||
@@ -247,68 +227,107 @@ TPeopleView::NewFile(entry_ref *ref)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
bool
|
||||||
TPeopleView::Save(void)
|
TPeopleView::IsSaved() const
|
||||||
{
|
{
|
||||||
for (int32 i = 0; gFields[i].attribute; i++) {
|
for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
|
||||||
const char *text = fField[i]->Text();
|
if (fControls.ItemAt(i)->HasChanged())
|
||||||
fFile->WriteAttr(gFields[i].attribute, B_STRING_TYPE, 0, text, strlen(text) + 1);
|
return false;
|
||||||
fField[i]->Update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TPeopleView::SetField(int32 index, bool update)
|
TPeopleView::Save()
|
||||||
{
|
{
|
||||||
char *text = NULL;
|
int32 count = fControls.CountItems();
|
||||||
attr_info info;
|
for (int32 i = 0; i < count; i++) {
|
||||||
if (fFile && fFile->GetAttrInfo(gFields[index].attribute, &info) == B_OK) {
|
AttributeTextControl* control = fControls.ItemAt(i);
|
||||||
text = (char *)calloc(info.size, 1);
|
const char* value = control->Text();
|
||||||
fFile->ReadAttr(gFields[index].attribute, B_STRING_TYPE, 0, text,
|
fFile->WriteAttr(control->Attribute().String(), B_STRING_TYPE, 0,
|
||||||
info.size);
|
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
|
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) {
|
if (update) {
|
||||||
fField[index]->SetText(data);
|
control->SetText(value);
|
||||||
fField[index]->Update();
|
control->Update();
|
||||||
} else {
|
} else {
|
||||||
BTextView* text = fField[index]->TextView();
|
BTextView* text = control->TextView();
|
||||||
|
|
||||||
int32 start, end;
|
int32 start, end;
|
||||||
text->GetSelection(&start, &end);
|
text->GetSelection(&start, &end);
|
||||||
if (start != end) {
|
if (start != end) {
|
||||||
text->Delete();
|
text->Delete();
|
||||||
text->Insert(data);
|
text->Insert(value);
|
||||||
} else if ((end = text->TextLength())) {
|
} else if ((end = text->TextLength())) {
|
||||||
text->Select(end, end);
|
text->Select(end, end);
|
||||||
text->Insert(",");
|
text->Insert(",");
|
||||||
text->Insert(data);
|
text->Insert(value);
|
||||||
text->Select(text->TextLength(), text->TextLength());
|
text->Select(text->TextLength(), text->TextLength());
|
||||||
} else
|
} else
|
||||||
fField[index]->SetText(data);
|
control->SetText(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Window()->Unlock();
|
UnlockLooper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TPeopleView::TextSelected(void)
|
TPeopleView::IsTextSelected() const
|
||||||
{
|
{
|
||||||
for (int32 loop = 0; loop < F_END; loop++) {
|
for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
|
||||||
BTextView* text = fField[loop]->TextView();
|
BTextView* text = fControls.ItemAt(i)->TextView();
|
||||||
|
|
||||||
int32 start, end;
|
int32 start, end;
|
||||||
text->GetSelection(&start, &end);
|
text->GetSelection(&start, &end);
|
||||||
|
|||||||
@@ -1,48 +1,69 @@
|
|||||||
//--------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PeopleView.h
|
|
||||||
//
|
|
||||||
// Written by: Robert Polic
|
|
||||||
//
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
/*
|
/*
|
||||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
* Copyright 2010, Haiku, Inc. All rights reserved.
|
||||||
This file may be used under the terms of the Be Sample Code License.
|
* Distributed under the terms of the MIT license.
|
||||||
*/
|
*
|
||||||
|
* Authors:
|
||||||
|
* Robert Polic
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*
|
||||||
|
* 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 <GridView.h>
|
#include <GridView.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
|
||||||
|
class AttributeTextControl;
|
||||||
|
class BFile;
|
||||||
class BPopUpMenu;
|
class BPopUpMenu;
|
||||||
class TTextControl;
|
|
||||||
|
enum {
|
||||||
|
M_SAVE = 'save',
|
||||||
|
M_REVERT = 'rvrt',
|
||||||
|
M_SELECT = 'slct',
|
||||||
|
M_GROUP_MENU = 'grmn',
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class TPeopleView : public BGridView {
|
class TPeopleView : public BGridView {
|
||||||
public:
|
public:
|
||||||
TPeopleView(const char* name, entry_ref* ref);
|
TPeopleView(const char* name,
|
||||||
~TPeopleView(void);
|
const char* categoryAttribute,
|
||||||
|
const entry_ref* ref);
|
||||||
|
virtual ~TPeopleView();
|
||||||
|
|
||||||
virtual void AttachedToWindow(void);
|
virtual void MakeFocus(bool focus = true);
|
||||||
virtual void MessageReceived(BMessage*);
|
virtual void MessageReceived(BMessage* message);
|
||||||
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);
|
|
||||||
|
|
||||||
private:
|
void AddAttribute(const char* label,
|
||||||
BFile *fFile;
|
const char* attribute);
|
||||||
BPopUpMenu *fGroups;
|
|
||||||
TTextControl *fField[F_END];
|
|
||||||
|
|
||||||
|
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<AttributeTextControl> AttributeList;
|
||||||
|
AttributeList fControls;
|
||||||
|
|
||||||
|
BString fCategoryAttribute;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* PEOPLEVIEW_H */
|
#endif // PEOPLE_VIEW_H
|
||||||
|
|||||||
+120
-118
@@ -1,14 +1,14 @@
|
|||||||
//--------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PeopleWindow.cpp
|
|
||||||
//
|
|
||||||
// Written by: Robert Polic
|
|
||||||
//
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
/*
|
/*
|
||||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
* Copyright 2005-2010, Haiku, Inc. All rights reserved.
|
||||||
This file may be used under the terms of the Be Sample Code License.
|
* Distributed under the terms of the MIT license.
|
||||||
*/
|
*
|
||||||
|
* Authors:
|
||||||
|
* Robert Polic
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*
|
||||||
|
* Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||||
|
* This file may be used under the terms of the Be Sample Code License.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "PeopleWindow.h"
|
#include "PeopleWindow.h"
|
||||||
|
|
||||||
@@ -41,11 +41,14 @@
|
|||||||
#define B_TRANSLATE_CONTEXT "People"
|
#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
|
BWindow(frame, title, B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE
|
||||||
| B_AUTO_UPDATE_SIZE_LIMITS),
|
| B_AUTO_UPDATE_SIZE_LIMITS),
|
||||||
fPanel(NULL)
|
fPanel(NULL),
|
||||||
|
fNameAttribute(nameAttribute)
|
||||||
{
|
{
|
||||||
BMenu* menu;
|
BMenu* menu;
|
||||||
BMenuItem* item;
|
BMenuItem* item;
|
||||||
@@ -55,7 +58,7 @@ TPeopleWindow::TPeopleWindow(BRect frame, const char *title, entry_ref *ref)
|
|||||||
menu->AddItem(item = new BMenuItem(
|
menu->AddItem(item = new BMenuItem(
|
||||||
B_TRANSLATE("New person" B_UTF8_ELLIPSIS),
|
B_TRANSLATE("New person" B_UTF8_ELLIPSIS),
|
||||||
new BMessage(M_NEW), 'N'));
|
new BMessage(M_NEW), 'N'));
|
||||||
item->SetTarget(NULL, be_app);
|
item->SetTarget(be_app);
|
||||||
menu->AddItem(new BMenuItem(B_TRANSLATE("Close"),
|
menu->AddItem(new BMenuItem(B_TRANSLATE("Close"),
|
||||||
new BMessage(B_QUIT_REQUESTED), 'W'));
|
new BMessage(B_QUIT_REQUESTED), 'W'));
|
||||||
menu->AddSeparatorItem();
|
menu->AddSeparatorItem();
|
||||||
@@ -71,66 +74,59 @@ TPeopleWindow::TPeopleWindow(BRect frame, const char *title, entry_ref *ref)
|
|||||||
menu->AddSeparatorItem();
|
menu->AddSeparatorItem();
|
||||||
item = new BMenuItem(B_TRANSLATE("Quit"),
|
item = new BMenuItem(B_TRANSLATE("Quit"),
|
||||||
new BMessage(B_QUIT_REQUESTED), 'Q');
|
new BMessage(B_QUIT_REQUESTED), 'Q');
|
||||||
item->SetTarget(NULL, be_app);
|
item->SetTarget(be_app);
|
||||||
menu->AddItem(item);
|
menu->AddItem(item);
|
||||||
menuBar->AddItem(menu);
|
menuBar->AddItem(menu);
|
||||||
|
|
||||||
menu = new BMenu(B_TRANSLATE("Edit"));
|
menu = new BMenu(B_TRANSLATE("Edit"));
|
||||||
menu->AddItem(fUndo = new BMenuItem(B_TRANSLATE("Undo"),
|
menu->AddItem(fUndo = new BMenuItem(B_TRANSLATE("Undo"),
|
||||||
new BMessage(B_UNDO), 'Z'));
|
new BMessage(B_UNDO), 'Z'));
|
||||||
fUndo->SetTarget(NULL, this);
|
|
||||||
fUndo->SetEnabled(false);
|
fUndo->SetEnabled(false);
|
||||||
menu->AddSeparatorItem();
|
menu->AddSeparatorItem();
|
||||||
menu->AddItem(fCut = new BMenuItem(B_TRANSLATE("Cut"),
|
menu->AddItem(fCut = new BMenuItem(B_TRANSLATE("Cut"),
|
||||||
new BMessage(B_CUT), 'X'));
|
new BMessage(B_CUT), 'X'));
|
||||||
fCut->SetTarget(NULL, this);
|
|
||||||
menu->AddItem(fCopy = new BMenuItem(B_TRANSLATE("Copy"),
|
menu->AddItem(fCopy = new BMenuItem(B_TRANSLATE("Copy"),
|
||||||
new BMessage(B_COPY), 'C'));
|
new BMessage(B_COPY), 'C'));
|
||||||
fCopy->SetTarget(NULL, this);
|
|
||||||
menu->AddItem(fPaste = new BMenuItem(B_TRANSLATE("Paste"),
|
menu->AddItem(fPaste = new BMenuItem(B_TRANSLATE("Paste"),
|
||||||
new BMessage(B_PASTE), 'V'));
|
new BMessage(B_PASTE), 'V'));
|
||||||
fPaste->SetTarget(NULL, this);
|
BMenuItem* selectAllItem = new BMenuItem(B_TRANSLATE("Select all"),
|
||||||
menu->AddItem(item = new BMenuItem(B_TRANSLATE("Select all"),
|
new BMessage(M_SELECT), 'A');
|
||||||
new BMessage(M_SELECT), 'A'));
|
menu->AddItem(selectAllItem);
|
||||||
item->SetTarget(NULL, this);
|
|
||||||
menuBar->AddItem(menu);
|
menuBar->AddItem(menu);
|
||||||
|
|
||||||
if (ref) {
|
if (ref != NULL) {
|
||||||
fRef = new entry_ref(*ref);
|
|
||||||
SetTitle(ref->name);
|
SetTitle(ref->name);
|
||||||
WatchChanges(true);
|
_SetToRef(new entry_ref(*ref));
|
||||||
} else
|
} else
|
||||||
fRef = NULL;
|
_SetToRef(NULL);
|
||||||
|
|
||||||
fView = new TPeopleView("PeopleView", fRef);
|
fView = new TPeopleView("PeopleView", categoryAttribute, fRef);
|
||||||
|
|
||||||
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
|
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
|
||||||
.SetInsets(0, 0, 0, 0)
|
.SetInsets(0, 0, 0, 0)
|
||||||
.Add(menuBar)
|
.Add(menuBar)
|
||||||
.Add(fView);
|
.Add(fView);
|
||||||
|
|
||||||
|
fRevert->SetTarget(fView);
|
||||||
|
selectAllItem->SetTarget(fView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TPeopleWindow::~TPeopleWindow(void)
|
TPeopleWindow::~TPeopleWindow()
|
||||||
{
|
{
|
||||||
if (fRef)
|
_SetToRef(NULL);
|
||||||
WatchChanges(false);
|
|
||||||
|
|
||||||
delete fRef;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TPeopleWindow::MenusBeginning(void)
|
TPeopleWindow::MenusBeginning()
|
||||||
{
|
{
|
||||||
bool enabled;
|
bool enabled = !fView->IsSaved();
|
||||||
bool isRedo;
|
|
||||||
|
|
||||||
enabled = fView->CheckSave();
|
|
||||||
fSave->SetEnabled(enabled);
|
fSave->SetEnabled(enabled);
|
||||||
fRevert->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);
|
fUndo->SetEnabled(state != B_UNDO_UNAVAILABLE);
|
||||||
|
|
||||||
if (isRedo)
|
if (isRedo)
|
||||||
@@ -138,7 +134,7 @@ TPeopleWindow::MenusBeginning(void)
|
|||||||
else
|
else
|
||||||
fUndo->SetLabel(B_TRANSLATE("Undo"));
|
fUndo->SetLabel(B_TRANSLATE("Undo"));
|
||||||
|
|
||||||
enabled = fView->TextSelected();
|
enabled = fView->IsTextSelected();
|
||||||
fCut->SetEnabled(enabled);
|
fCut->SetEnabled(enabled);
|
||||||
fCopy->SetEnabled(enabled);
|
fCopy->SetEnabled(enabled);
|
||||||
|
|
||||||
@@ -154,7 +150,6 @@ void
|
|||||||
TPeopleWindow::MessageReceived(BMessage* msg)
|
TPeopleWindow::MessageReceived(BMessage* msg)
|
||||||
{
|
{
|
||||||
char str[256];
|
char str[256];
|
||||||
entry_ref dir;
|
|
||||||
BDirectory directory;
|
BDirectory directory;
|
||||||
BEntry entry;
|
BEntry entry;
|
||||||
BFile file;
|
BFile file;
|
||||||
@@ -166,6 +161,7 @@ TPeopleWindow::MessageReceived(BMessage* msg)
|
|||||||
SaveAs();
|
SaveAs();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// supposed to fall through
|
||||||
case M_REVERT:
|
case M_REVERT:
|
||||||
case M_SELECT:
|
case M_SELECT:
|
||||||
fView->MessageReceived(msg);
|
fView->MessageReceived(msg);
|
||||||
@@ -175,16 +171,11 @@ TPeopleWindow::MessageReceived(BMessage* msg)
|
|||||||
SaveAs();
|
SaveAs();
|
||||||
break;
|
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:
|
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);
|
msg->FindString("name", &name);
|
||||||
directory.SetTo(&dir);
|
directory.SetTo(&dir);
|
||||||
if (directory.InitCheck() == B_NO_ERROR) {
|
if (directory.InitCheck() == B_NO_ERROR) {
|
||||||
@@ -196,14 +187,9 @@ TPeopleWindow::MessageReceived(BMessage* msg)
|
|||||||
|
|
||||||
directory.FindEntry(name, &entry);
|
directory.FindEntry(name, &entry);
|
||||||
entry.GetRef(&dir);
|
entry.GetRef(&dir);
|
||||||
if (fRef) {
|
_SetToRef(new entry_ref(dir));
|
||||||
WatchChanges(false);
|
|
||||||
delete fRef;
|
|
||||||
}
|
|
||||||
fRef = new entry_ref(dir);
|
|
||||||
WatchChanges(true);
|
|
||||||
SetTitle(fRef->name);
|
SetTitle(fRef->name);
|
||||||
fView->NewFile(fRef);
|
fView->CreateFile(fRef);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sprintf(str, B_TRANSLATE("Could not create %s."), name);
|
sprintf(str, B_TRANSLATE("Could not create %s."), name);
|
||||||
@@ -212,18 +198,15 @@ TPeopleWindow::MessageReceived(BMessage* msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case B_NODE_MONITOR:
|
case B_NODE_MONITOR:
|
||||||
{
|
{
|
||||||
int32 opcode;
|
int32 opcode;
|
||||||
if (msg->FindInt32("opcode", &opcode) == B_OK) {
|
if (msg->FindInt32("opcode", &opcode) == B_OK) {
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case B_ENTRY_REMOVED:
|
case B_ENTRY_REMOVED:
|
||||||
// We lost our file. Close the window by quiting its
|
// We lost our file. Close the window.
|
||||||
// looper.
|
|
||||||
delete fRef;
|
|
||||||
fRef = NULL;
|
|
||||||
|
|
||||||
PostMessage(B_QUIT_REQUESTED);
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -244,7 +227,6 @@ TPeopleWindow::MessageReceived(BMessage* msg)
|
|||||||
delete fRef;
|
delete fRef;
|
||||||
fRef = new entry_ref(device, directory, name.String());
|
fRef = new entry_ref(device, directory, name.String());
|
||||||
|
|
||||||
|
|
||||||
// And our window title.
|
// And our window title.
|
||||||
SetTitle(name);
|
SetTitle(name);
|
||||||
|
|
||||||
@@ -255,11 +237,8 @@ TPeopleWindow::MessageReceived(BMessage* msg)
|
|||||||
&volume);
|
&volume);
|
||||||
BPath folder(fRef);
|
BPath folder(fRef);
|
||||||
folder.GetParent(&folder);
|
folder.GetParent(&folder);
|
||||||
if (folder == trash) {
|
if (folder == trash)
|
||||||
delete fRef;
|
|
||||||
fRef = NULL;
|
|
||||||
PostMessage(B_QUIT_REQUESTED);
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -268,13 +247,8 @@ TPeopleWindow::MessageReceived(BMessage* msg)
|
|||||||
{
|
{
|
||||||
// An attribute was updated.
|
// An attribute was updated.
|
||||||
BString attr;
|
BString attr;
|
||||||
if (msg->FindString("attr", &attr) == B_OK) {
|
if (msg->FindString("attr", &attr) == B_OK)
|
||||||
for (int32 i = 0; gFields[i].attribute; i++) {
|
fView->SetAttribute(attr.String(), true);
|
||||||
if (attr == gFields[i].attribute) {
|
|
||||||
fView->SetField(i, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,11 +263,11 @@ TPeopleWindow::MessageReceived(BMessage* msg)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TPeopleWindow::QuitRequested(void)
|
TPeopleWindow::QuitRequested()
|
||||||
{
|
{
|
||||||
status_t result;
|
status_t result;
|
||||||
|
|
||||||
if (fView->CheckSave()) {
|
if (!fView->IsSaved()) {
|
||||||
result = (new BAlert("", B_TRANSLATE("Save changes before quitting?"),
|
result = (new BAlert("", B_TRANSLATE("Save changes before quitting?"),
|
||||||
B_TRANSLATE("Cancel"), B_TRANSLATE("Quit"),
|
B_TRANSLATE("Cancel"), B_TRANSLATE("Quit"),
|
||||||
B_TRANSLATE("Save")))->Go();
|
B_TRANSLATE("Save")))->Go();
|
||||||
@@ -322,9 +296,68 @@ TPeopleWindow::QuitRequested(void)
|
|||||||
|
|
||||||
|
|
||||||
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) {
|
while (*name) {
|
||||||
if (*name == '/')
|
if (*name == '/')
|
||||||
*name = '-';
|
*name = '-';
|
||||||
@@ -334,52 +367,21 @@ TPeopleWindow::DefaultName(char *name)
|
|||||||
|
|
||||||
|
|
||||||
void
|
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
|
void
|
||||||
TPeopleWindow::SaveAs(void)
|
TPeopleWindow::_WatchChanges(bool enable)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
if (fRef == NULL)
|
if (fRef == NULL)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,56 +1,71 @@
|
|||||||
//--------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PeopleWindow.h
|
|
||||||
//
|
|
||||||
// Written by: Robert Polic
|
|
||||||
//
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
/*
|
/*
|
||||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
* Copyright 2010, Haiku, Inc. All rights reserved.
|
||||||
This file may be used under the terms of the Be Sample Code License.
|
* 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 <String.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
#ifndef PEOPLEWINDOW_H
|
|
||||||
#define PEOPLEWINDOW_H
|
|
||||||
|
|
||||||
#define TITLE_BAR_HEIGHT 25
|
#define TITLE_BAR_HEIGHT 25
|
||||||
#define WIND_WIDTH 321
|
#define WIND_WIDTH 321
|
||||||
#define WIND_HEIGHT 340
|
#define WIND_HEIGHT 340
|
||||||
|
|
||||||
|
|
||||||
class TPeopleView;
|
class TPeopleView;
|
||||||
class BFilePanel;
|
class BFilePanel;
|
||||||
class BMenuItem;
|
class BMenuItem;
|
||||||
|
|
||||||
#include <Window.h>
|
|
||||||
//====================================================================
|
|
||||||
|
|
||||||
class TPeopleWindow : public BWindow {
|
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:
|
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*);
|
virtual void MenusBeginning();
|
||||||
~TPeopleWindow(void);
|
virtual void MessageReceived(BMessage* message);
|
||||||
virtual void MenusBeginning(void);
|
virtual bool QuitRequested();
|
||||||
virtual void MessageReceived(BMessage*);
|
virtual void Show();
|
||||||
virtual bool QuitRequested(void);
|
|
||||||
void DefaultName(char*);
|
void AddAttribute(const char* label,
|
||||||
void SetField(int32, char*);
|
const char* attribute);
|
||||||
void SaveAs(void);
|
|
||||||
|
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
|
||||||
|
|||||||
@@ -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 <string.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <Font.h>
|
|
||||||
|
|
||||||
#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();
|
|
||||||
}
|
|
||||||
@@ -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 <String.h>
|
|
||||||
#include <TextControl.h>
|
|
||||||
|
|
||||||
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 */
|
|
||||||
+12
-17
@@ -1,24 +1,19 @@
|
|||||||
//--------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// main.cpp
|
|
||||||
//
|
|
||||||
// Written by: Robert Polic
|
|
||||||
//
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
/*
|
/*
|
||||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
* Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||||
This file may be used under the terms of the Be Sample Code License.
|
* This file may be used under the terms of the Be Sample Code License.
|
||||||
*/
|
*
|
||||||
|
* Authors:
|
||||||
|
* Robert Polic
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "PeopleApp.h"
|
#include "PeopleApp.h"
|
||||||
|
|
||||||
int main(void)
|
|
||||||
|
int
|
||||||
|
main(int, char**)
|
||||||
{
|
{
|
||||||
TPeopleApp *app;
|
TPeopleApp app;
|
||||||
|
app.Run();
|
||||||
app = new TPeopleApp();
|
|
||||||
app->Run();
|
|
||||||
|
|
||||||
delete app;
|
|
||||||
return B_NO_ERROR;
|
return B_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user