diff --git a/src/apps/people/Jamfile b/src/apps/people/Jamfile index a5c34fcd3b..c4ad8a4661 100644 --- a/src/apps/people/Jamfile +++ b/src/apps/people/Jamfile @@ -1,20 +1,25 @@ SubDir HAIKU_TOP src apps people ; +UseLibraryHeaders icon ; UsePrivateHeaders shared ; -Application People : main.cpp +Application People : + main.cpp AttributeTextControl.cpp PeopleApp.cpp PersonView.cpp - PersonWindow.cpp - : libbe.so libtracker.so $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS) + PersonWindow.cpp + PictureView.cpp + : libicon.a be tracker translation + $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS) : People.rdef - ; +; -DoCatalogs People : +DoCatalogs People : x-vnd.Be-PEPL - : + : PeopleApp.cpp PersonView.cpp PersonWindow.cpp + # PictureView.cpp ; diff --git a/src/apps/people/PersonView.cpp b/src/apps/people/PersonView.cpp index 6552f321a1..05e8f63577 100644 --- a/src/apps/people/PersonView.cpp +++ b/src/apps/people/PersonView.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -27,10 +28,13 @@ #include #include #include +#include +#include #include #include #include "AttributeTextControl.h" +#include "PictureView.h" #undef B_TRANSLATE_CONTEXT @@ -43,16 +47,27 @@ PersonView::PersonView(const char* name, const char* categoryAttribute, BGridView(), fGroups(NULL), fControls(20, false), - fCategoryAttribute(categoryAttribute) + fCategoryAttribute(categoryAttribute), + fPictureView(NULL) { SetName(name); + SetFlags(Flags() | B_WILL_DRAW); + if (ref) fFile = new BFile(ref, O_RDWR); else fFile = NULL; float spacing = be_control_look->DefaultItemSpacing(); - GridLayout()->SetInsets(spacing, spacing, spacing, spacing); + BGridLayout* layout = GridLayout(); + layout->SetInsets(spacing, spacing, spacing, spacing); + + // Add picture "field" + fPictureView = new PictureView(96, 112, ref); + + layout->AddView(fPictureView, 0, 0, 1, 5); + layout->ItemAt(0, 0)->SetExplicitAlignment( + BAlignment(B_ALIGN_CENTER, B_ALIGN_TOP)); } @@ -65,13 +80,19 @@ PersonView::~PersonView() void PersonView::AddAttribute(const char* label, const char* attribute) { - // TODO: We could check if this attribute has already been added. + // Check if this attribute has already been added. + AttributeTextControl* control = NULL; + for (int32 i = fControls.CountItems() - 1; i >= 0; i--) { + if (fControls.ItemAt(i)->Attribute() == attribute) { + return; + } + } - AttributeTextControl* control = new AttributeTextControl(label, attribute); + control = new AttributeTextControl(label, attribute); fControls.AddItem(control); BGridLayout* layout = GridLayout(); - int32 row = layout->CountRows(); + int32 row = fControls.CountItems(); if (fCategoryAttribute == attribute) { // Special case the category attribute. The Group popup field will @@ -82,13 +103,13 @@ PersonView::AddAttribute(const char* label, const char* attribute) BMenuField* field = new BMenuField("", "", fGroups); field->SetEnabled(true); - layout->AddView(field, 0, row); + layout->AddView(field, 1, row); control->SetLabel(""); - layout->AddView(control, 1, row); + layout->AddView(control, 2, row); } else { - layout->AddItem(control->CreateLabelLayoutItem(), 0, row); - layout->AddItem(control->CreateTextViewLayoutItem(), 1, row); + layout->AddItem(control->CreateLabelLayoutItem(), 1, row); + layout->AddItem(control->CreateTextViewLayoutItem(), 2, row); } SetAttribute(attribute, true); @@ -114,6 +135,9 @@ PersonView::MessageReceived(BMessage* msg) break; case M_REVERT: + if (fPictureView) + fPictureView->Revert(); + for (int32 i = fControls.CountItems() - 1; i >= 0; i--) fControls.ItemAt(i)->Revert(); break; @@ -140,6 +164,21 @@ PersonView::MessageReceived(BMessage* msg) } +void +PersonView::Draw(BRect updateRect) +{ + if (!fPictureView) + return; + + // Draw a alert/get info-like strip + BRect stripeRect = Bounds(); + float pictureWidth = /*fPictureView->Bounds().Width() */ 96; + stripeRect.right = 10 + pictureWidth / 2; + SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); + FillRect(stripeRect); +} + + void PersonView::BuildGroupMenu() { @@ -213,7 +252,7 @@ PersonView::BuildGroupMenu() if (count == 0) { fGroups->AddItem(item = new BMenuItem( - B_TRANSLATE_WITH_CONTEXT("none", "Groups list"), + B_TRANSLATE_WITH_CONTEXT("none", "Groups list"), new BMessage(M_GROUP_MENU))); item->SetEnabled(false); } @@ -234,6 +273,9 @@ PersonView::CreateFile(const entry_ref* ref) bool PersonView::IsSaved() const { + if (fPictureView && fPictureView->HasChanged()) + return false; + for (int32 i = fControls.CountItems() - 1; i >= 0; i--) { if (fControls.ItemAt(i)->HasChanged()) return false; @@ -254,6 +296,19 @@ PersonView::Save() value, strlen(value) + 1); control->Update(); } + + // Write the picture, if any, in the person file content + if (fPictureView) { + // trim previous content + fFile->Seek(0, SEEK_SET); + fFile->SetSize(0); + if (fPictureView->Bitmap()) { + BBitmapStream stream(fPictureView->Bitmap()); + BTranslatorRoster* roster = BTranslatorRoster::Default(); + roster->Translate(&stream, NULL, NULL, fFile, B_PNG_FORMAT, + B_TRANSLATOR_BITMAP); + } + } } @@ -264,7 +319,7 @@ PersonView::AttributeValue(const char* attribute) const if (fControls.ItemAt(i)->Attribute() == attribute) return fControls.ItemAt(i)->Text(); } - + return ""; } @@ -327,6 +382,14 @@ PersonView::SetAttribute(const char* attribute, const char* value, } +void +PersonView::UpdatePicture(const entry_ref* ref) +{ + if (fPictureView) + fPictureView->Update(ref); +} + + bool PersonView::IsTextSelected() const { diff --git a/src/apps/people/PersonView.h b/src/apps/people/PersonView.h index 1e4c703904..ea74522527 100644 --- a/src/apps/people/PersonView.h +++ b/src/apps/people/PersonView.h @@ -21,6 +21,7 @@ class AttributeTextControl; class BFile; class BPopUpMenu; +class PictureView; enum { M_SAVE = 'save', @@ -39,6 +40,7 @@ public: virtual void MakeFocus(bool focus = true); virtual void MessageReceived(BMessage* message); + virtual void Draw(BRect updateRect); void AddAttribute(const char* label, const char* attribute); @@ -55,6 +57,8 @@ public: void SetAttribute(const char* attribute, const char* value, bool update); + void UpdatePicture(const entry_ref* ref); + bool IsTextSelected() const; private: @@ -64,6 +68,7 @@ private: AttributeList fControls; BString fCategoryAttribute; + PictureView* fPictureView; }; #endif // PERSON_VIEW_H diff --git a/src/apps/people/PersonWindow.cpp b/src/apps/people/PersonWindow.cpp index 4160a6283e..2e8e443836 100644 --- a/src/apps/people/PersonWindow.cpp +++ b/src/apps/people/PersonWindow.cpp @@ -62,7 +62,7 @@ PersonWindow::PersonWindow(BRect frame, const char* title, menu->AddItem(new BMenuItem(B_TRANSLATE("Close"), new BMessage(B_QUIT_REQUESTED), 'W')); menu->AddSeparatorItem(); - menu->AddItem(fSave = new BMenuItem(B_TRANSLATE("Save"), + menu->AddItem(fSave = new BMenuItem(B_TRANSLATE("Save"), new BMessage(M_SAVE), 'S')); fSave->SetEnabled(FALSE); menu->AddItem(new BMenuItem( @@ -72,28 +72,28 @@ PersonWindow::PersonWindow(BRect frame, const char* title, new BMessage(M_REVERT), 'R')); fRevert->SetEnabled(FALSE); menu->AddSeparatorItem(); - item = new BMenuItem(B_TRANSLATE("Quit"), + item = new BMenuItem(B_TRANSLATE("Quit"), new BMessage(B_QUIT_REQUESTED), 'Q'); item->SetTarget(be_app); menu->AddItem(item); menuBar->AddItem(menu); 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')); fUndo->SetEnabled(false); menu->AddSeparatorItem(); - menu->AddItem(fCut = new BMenuItem(B_TRANSLATE("Cut"), + menu->AddItem(fCut = new BMenuItem(B_TRANSLATE("Cut"), new BMessage(B_CUT), 'X')); - menu->AddItem(fCopy = new BMenuItem(B_TRANSLATE("Copy"), + menu->AddItem(fCopy = new BMenuItem(B_TRANSLATE("Copy"), new BMessage(B_COPY), 'C')); - menu->AddItem(fPaste = new BMenuItem(B_TRANSLATE("Paste"), + menu->AddItem(fPaste = new BMenuItem(B_TRANSLATE("Paste"), new BMessage(B_PASTE), 'V')); BMenuItem* selectAllItem = new BMenuItem(B_TRANSLATE("Select all"), new BMessage(M_SELECT), 'A'); menu->AddItem(selectAllItem); menu->AddSeparatorItem(); - menu->AddItem(item = new BMenuItem(B_TRANSLATE("Configure attributes"), + menu->AddItem(item = new BMenuItem(B_TRANSLATE("Configure attributes"), new BMessage(M_CONFIGURE_ATTRIBUTES), 'F')); item->SetTarget(be_app); menuBar->AddItem(menu); @@ -203,7 +203,7 @@ PersonWindow::MessageReceived(BMessage* msg) } break; } - + case B_NODE_MONITOR: { int32 opcode; @@ -213,7 +213,7 @@ PersonWindow::MessageReceived(BMessage* msg) // We lost our file. Close the window. PostMessage(B_QUIT_REQUESTED); break; - + case B_ENTRY_MOVED: { // We may have renamed our entry. Obtain relevant data @@ -223,14 +223,14 @@ PersonWindow::MessageReceived(BMessage* msg) int64 directory; msg->FindInt64("to directory", &directory); - + int32 device; msg->FindInt32("device", &device); - + // Update our ref. delete fRef; - fRef = new entry_ref(device, directory, name.String()); - + fRef = new entry_ref(device, directory, name.String()); + // And our window title. SetTitle(name); @@ -246,7 +246,7 @@ PersonWindow::MessageReceived(BMessage* msg) break; } - + case B_ATTR_CHANGED: { // An attribute was updated. @@ -254,7 +254,10 @@ PersonWindow::MessageReceived(BMessage* msg) if (msg->FindString("attr", &attr) == B_OK) fView->SetAttribute(attr.String(), true); break; - } + } + case B_STAT_CHANGED: + fView->UpdatePicture(fRef); + break; } } break; @@ -273,7 +276,7 @@ PersonWindow::QuitRequested() if (!fView->IsSaved()) { 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(); if (result == 2) { if (fRef) @@ -294,7 +297,7 @@ PersonWindow::QuitRequested() be_app->PostMessage(&message); be_app->Unlock(); } - + return true; } @@ -345,7 +348,7 @@ PersonWindow::SaveAs() else fPanel->Window()->Activate(); fPanel->Window()->Unlock(); - } + } } @@ -391,10 +394,10 @@ PersonWindow::_WatchChanges(bool enable) return; node_ref nodeRef; - + BNode node(fRef); node.GetNodeRef(&nodeRef); - + uint32 flags; BString action; @@ -407,7 +410,7 @@ PersonWindow::_WatchChanges(bool enable) 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/PersonWindow.h b/src/apps/people/PersonWindow.h index c3e9a37519..3916a6e707 100644 --- a/src/apps/people/PersonWindow.h +++ b/src/apps/people/PersonWindow.h @@ -17,7 +17,7 @@ #define TITLE_BAR_HEIGHT 25 -#define WIND_WIDTH 321 +#define WIND_WIDTH 420 #define WIND_HEIGHT 340