From a7291500f18aebbbe4b39ea0526154f512034ac5 Mon Sep 17 00:00:00 2001 From: "Bruno G. Albuquerque" Date: Thu, 3 Sep 2009 00:58:12 +0000 Subject: [PATCH] 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 --- src/apps/people/PeopleView.cpp | 17 ++++++ src/apps/people/PeopleView.h | 1 + src/apps/people/PeopleWindow.cpp | 89 +++++++++++++++++++++++++++++++- src/apps/people/PeopleWindow.h | 2 + 4 files changed, 108 insertions(+), 1 deletion(-) diff --git a/src/apps/people/PeopleView.cpp b/src/apps/people/PeopleView.cpp index 3922dc4cc7..c9e598dcda 100644 --- a/src/apps/people/PeopleView.cpp +++ b/src/apps/people/PeopleView.cpp @@ -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) { diff --git a/src/apps/people/PeopleView.h b/src/apps/people/PeopleView.h index 3d1fbe05fc..97d7fb0cc9 100644 --- a/src/apps/people/PeopleView.h +++ b/src/apps/people/PeopleView.h @@ -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); diff --git a/src/apps/people/PeopleWindow.cpp b/src/apps/people/PeopleWindow.cpp index ce9008df88..a1e41259f2 100644 --- a/src/apps/people/PeopleWindow.cpp +++ b/src/apps/people/PeopleWindow.cpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include #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()); + } +} diff --git a/src/apps/people/PeopleWindow.h b/src/apps/people/PeopleWindow.h index 3d6457ffad..4f3132c724 100644 --- a/src/apps/people/PeopleWindow.h +++ b/src/apps/people/PeopleWindow.h @@ -28,6 +28,8 @@ class TPeopleWindow : public BWindow { private: + void WatchChanges(bool); + BFilePanel *fPanel; BMenuItem *fCopy; BMenuItem *fCut;