People was always more of a tech-demo than a real app, so I just decided to

make it more interesting in this respect.

- Uses node monitors to react to external changes. Updates the window
  contents accordingly.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32912 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Bruno G. Albuquerque 2009-09-03 00:58:12 +00:00
parent a6996bf541
commit a7291500f1
4 changed files with 108 additions and 1 deletions

View File

@ -253,6 +253,23 @@ TPeopleView::Save(void)
}
void
TPeopleView::SetField(int32 index, bool update)
{
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);
}
SetField(index, text, update);
free(text);
}
void
TPeopleView::SetField(int32 index, char *data, bool update)
{

View File

@ -35,6 +35,7 @@ class TPeopleView : public BView {
const char* GetField(int32);
void NewFile(entry_ref*);
void Save(void);
void SetField(int32, bool);
void SetField(int32, char*, bool);
bool TextSelected(void);

View File

@ -20,6 +20,8 @@
#include <Font.h>
#include <Clipboard.h>
#include <TextView.h>
#include <NodeMonitor.h>
#include <String.h>
#include "PeopleApp.h"
#include "PeopleView.h"
@ -71,6 +73,7 @@ TPeopleWindow::TPeopleWindow(BRect frame, const char *title, entry_ref *ref)
if (ref) {
fRef = new entry_ref(*ref);
SetTitle(ref->name);
WatchChanges(true);
} else
fRef = NULL;
@ -85,6 +88,9 @@ TPeopleWindow::TPeopleWindow(BRect frame, const char *title, entry_ref *ref)
TPeopleWindow::~TPeopleWindow(void)
{
if (fRef)
WatchChanges(false);
delete fRef;
delete fPanel;
}
@ -166,9 +172,12 @@ TPeopleWindow::MessageReceived(BMessage* msg)
directory.FindEntry(name, &entry);
entry.GetRef(&dir);
if (fRef)
if (fRef) {
WatchChanges(false);
delete fRef;
}
fRef = new entry_ref(dir);
WatchChanges(true);
SetTitle(fRef->name);
fView->NewFile(fRef);
}
@ -179,6 +188,54 @@ 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. Reset everything. We don't need
// to explicitly disable the node monitor.
delete fRef;
fRef = NULL;
for (int32 i = 0; gFields[i].attribute; i++)
fView->SetField(i, "", true);
SetTitle("New Person");
break;
case B_ENTRY_MOVED:
{
// We may have renamed our entry. Update the title
// just in case.
BString name;
if (msg->FindString("name", &name) == B_OK)
SetTitle(name);
}
break;
case B_ATTR_CHANGED:
{
// 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);
}
}
}
}
break;
default:
msg->PrintToStream();
}
}
}
break;
default:
BWindow::MessageReceived(msg);
@ -283,3 +340,33 @@ TPeopleWindow::SaveAs(void)
fPanel->Window()->Unlock();
}
}
void
TPeopleWindow::WatchChanges(bool enable)
{
if (fRef == NULL)
return;
node_ref nodeRef;
BNode node(fRef);
node.GetNodeRef(&nodeRef);
uint32 flags;
BString action;
if (enable) {
// Start watching.
flags = B_WATCH_ALL;
action = "starting";
} else {
// Stop watching.
flags = B_STOP_WATCHING;
action = "stoping";
}
if (watch_node(&nodeRef, flags, this) != B_OK) {
printf("Error %s node monitor.\n", action.String());
}
}

View File

@ -28,6 +28,8 @@ class TPeopleWindow : public BWindow {
private:
void WatchChanges(bool);
BFilePanel *fPanel;
BMenuItem *fCopy;
BMenuItem *fCut;