xref: /haiku/src/apps/people/PersonView.cpp (revision 964b6e8090e0172180c456a93dcbc1454b79f252)
1968ec77eSStephan Aßmus /*
2968ec77eSStephan Aßmus  * Copyright 2010, Haiku, Inc. All rights reserved.
3968ec77eSStephan Aßmus  * Distributed under the terms of the MIT license.
4968ec77eSStephan Aßmus  *
5968ec77eSStephan Aßmus  * Authors:
6968ec77eSStephan Aßmus  *		Robert Polic
7968ec77eSStephan Aßmus  *		Stephan Aßmus <superstippi@gmx.de>
8968ec77eSStephan Aßmus  *
9968ec77eSStephan Aßmus  * Copyright 1999, Be Incorporated.   All Rights Reserved.
10968ec77eSStephan Aßmus  * This file may be used under the terms of the Be Sample Code License.
11968ec77eSStephan Aßmus  */
12968ec77eSStephan Aßmus 
13968ec77eSStephan Aßmus 
14968ec77eSStephan Aßmus #include "PersonView.h"
15968ec77eSStephan Aßmus 
16968ec77eSStephan Aßmus #include <stdio.h>
17968ec77eSStephan Aßmus #include <stdlib.h>
18968ec77eSStephan Aßmus #include <string.h>
19968ec77eSStephan Aßmus 
2084627497SPhilippe Houdoin #include <BitmapStream.h>
21968ec77eSStephan Aßmus #include <Catalog.h>
22968ec77eSStephan Aßmus #include <fs_attr.h>
23968ec77eSStephan Aßmus #include <Box.h>
24968ec77eSStephan Aßmus #include <ControlLook.h>
25968ec77eSStephan Aßmus #include <GridLayout.h>
26968ec77eSStephan Aßmus #include <Locale.h>
27968ec77eSStephan Aßmus #include <MenuField.h>
28968ec77eSStephan Aßmus #include <MenuItem.h>
29968ec77eSStephan Aßmus #include <PopUpMenu.h>
30968ec77eSStephan Aßmus #include <Query.h>
3184627497SPhilippe Houdoin #include <TranslationUtils.h>
3284627497SPhilippe Houdoin #include <Translator.h>
33968ec77eSStephan Aßmus #include <VolumeRoster.h>
34968ec77eSStephan Aßmus #include <Window.h>
35968ec77eSStephan Aßmus 
36968ec77eSStephan Aßmus #include "AttributeTextControl.h"
3784627497SPhilippe Houdoin #include "PictureView.h"
38968ec77eSStephan Aßmus 
39968ec77eSStephan Aßmus 
40546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
41546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "People"
42968ec77eSStephan Aßmus 
43968ec77eSStephan Aßmus 
PersonView(const char * name,const char * categoryAttribute,const entry_ref * ref)44968ec77eSStephan Aßmus PersonView::PersonView(const char* name, const char* categoryAttribute,
45968ec77eSStephan Aßmus 		const entry_ref *ref)
46968ec77eSStephan Aßmus 	:
47968ec77eSStephan Aßmus 	BGridView(),
4889aa6cbeSPhilippe Houdoin 	fLastModificationTime(0),
49fd44ef42SStephan Aßmus 	fGroups(NULL),
50968ec77eSStephan Aßmus 	fControls(20, false),
5184627497SPhilippe Houdoin 	fCategoryAttribute(categoryAttribute),
5289aa6cbeSPhilippe Houdoin 	fPictureView(NULL),
5389aa6cbeSPhilippe Houdoin 	fSaving(false)
54968ec77eSStephan Aßmus {
55968ec77eSStephan Aßmus 	SetName(name);
5684627497SPhilippe Houdoin 	SetFlags(Flags() | B_WILL_DRAW);
5784627497SPhilippe Houdoin 
58a09c983cSPhilippe Saint-Pierre 	fRef = ref;
59a09c983cSPhilippe Saint-Pierre 	BFile* file = NULL;
60a09c983cSPhilippe Saint-Pierre 	if (fRef != NULL)
61a09c983cSPhilippe Saint-Pierre 		file = new BFile(fRef, B_READ_ONLY);
62968ec77eSStephan Aßmus 
63e5dca0c2SPhilippe Houdoin 	// Add picture "field", using ID photo 35mm x 45mm ratio
64e5dca0c2SPhilippe Houdoin 	fPictureView = new PictureView(70, 90, ref);
6584627497SPhilippe Houdoin 
66d0ac6099SHumdinger 	BGridLayout* layout = GridLayout();
67d63ed584SAdrien Destugues 
68d63ed584SAdrien Destugues 	float spacing = be_control_look->DefaultItemSpacing();
69d63ed584SAdrien Destugues 	layout->SetInsets(spacing, spacing, spacing, spacing);
70d63ed584SAdrien Destugues 
7184627497SPhilippe Houdoin 	layout->AddView(fPictureView, 0, 0, 1, 5);
7284627497SPhilippe Houdoin 	layout->ItemAt(0, 0)->SetExplicitAlignment(
7384627497SPhilippe Houdoin 		BAlignment(B_ALIGN_CENTER, B_ALIGN_TOP));
7489aa6cbeSPhilippe Houdoin 
75a09c983cSPhilippe Saint-Pierre 	if (file != NULL)
76a09c983cSPhilippe Saint-Pierre 		file->GetModificationTime(&fLastModificationTime);
77a09c983cSPhilippe Saint-Pierre 	delete file;
78968ec77eSStephan Aßmus }
79968ec77eSStephan Aßmus 
80968ec77eSStephan Aßmus 
~PersonView()81968ec77eSStephan Aßmus PersonView::~PersonView()
82968ec77eSStephan Aßmus {
83968ec77eSStephan Aßmus }
84968ec77eSStephan Aßmus 
85968ec77eSStephan Aßmus 
86968ec77eSStephan Aßmus void
AddAttribute(const char * label,const char * attribute)87968ec77eSStephan Aßmus PersonView::AddAttribute(const char* label, const char* attribute)
88968ec77eSStephan Aßmus {
8984627497SPhilippe Houdoin 	// Check if this attribute has already been added.
9084627497SPhilippe Houdoin 	AttributeTextControl* control = NULL;
9184627497SPhilippe Houdoin 	for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
9284627497SPhilippe Houdoin 		if (fControls.ItemAt(i)->Attribute() == attribute) {
9384627497SPhilippe Houdoin 			return;
9484627497SPhilippe Houdoin 		}
9584627497SPhilippe Houdoin 	}
96968ec77eSStephan Aßmus 
9784627497SPhilippe Houdoin 	control = new AttributeTextControl(label, attribute);
98968ec77eSStephan Aßmus 	fControls.AddItem(control);
99968ec77eSStephan Aßmus 
100968ec77eSStephan Aßmus 	BGridLayout* layout = GridLayout();
10184627497SPhilippe Houdoin 	int32 row = fControls.CountItems();
102968ec77eSStephan Aßmus 
103968ec77eSStephan Aßmus 	if (fCategoryAttribute == attribute) {
104968ec77eSStephan Aßmus 		// Special case the category attribute. The Group popup field will
105968ec77eSStephan Aßmus 		// be added as the label instead.
106968ec77eSStephan Aßmus 		fGroups = new BPopUpMenu(label);
107968ec77eSStephan Aßmus 		fGroups->SetRadioMode(false);
108968ec77eSStephan Aßmus 		BuildGroupMenu();
109968ec77eSStephan Aßmus 
110968ec77eSStephan Aßmus 		BMenuField* field = new BMenuField("", "", fGroups);
111968ec77eSStephan Aßmus 		field->SetEnabled(true);
11284627497SPhilippe Houdoin 		layout->AddView(field, 1, row);
113968ec77eSStephan Aßmus 
114968ec77eSStephan Aßmus 		control->SetLabel("");
11584627497SPhilippe Houdoin 		layout->AddView(control, 2, row);
116968ec77eSStephan Aßmus 	} else {
11784627497SPhilippe Houdoin 		layout->AddItem(control->CreateLabelLayoutItem(), 1, row);
11884627497SPhilippe Houdoin 		layout->AddItem(control->CreateTextViewLayoutItem(), 2, row);
119968ec77eSStephan Aßmus 	}
120968ec77eSStephan Aßmus 
121968ec77eSStephan Aßmus 	SetAttribute(attribute, true);
122968ec77eSStephan Aßmus }
123968ec77eSStephan Aßmus 
124968ec77eSStephan Aßmus 
125968ec77eSStephan Aßmus void
MakeFocus(bool focus)126968ec77eSStephan Aßmus PersonView::MakeFocus(bool focus)
127968ec77eSStephan Aßmus {
128968ec77eSStephan Aßmus 	if (focus && fControls.CountItems() > 0)
129968ec77eSStephan Aßmus 		fControls.ItemAt(0)->MakeFocus();
130968ec77eSStephan Aßmus 	else
131968ec77eSStephan Aßmus 		BView::MakeFocus(focus);
132968ec77eSStephan Aßmus }
133968ec77eSStephan Aßmus 
134968ec77eSStephan Aßmus 
135968ec77eSStephan Aßmus void
MessageReceived(BMessage * msg)136968ec77eSStephan Aßmus PersonView::MessageReceived(BMessage* msg)
137968ec77eSStephan Aßmus {
138968ec77eSStephan Aßmus 	switch (msg->what) {
139968ec77eSStephan Aßmus 		case M_SAVE:
140968ec77eSStephan Aßmus 			Save();
141968ec77eSStephan Aßmus 			break;
142968ec77eSStephan Aßmus 
143968ec77eSStephan Aßmus 		case M_REVERT:
14484627497SPhilippe Houdoin 			if (fPictureView)
14584627497SPhilippe Houdoin 				fPictureView->Revert();
14684627497SPhilippe Houdoin 
147968ec77eSStephan Aßmus 			for (int32 i = fControls.CountItems() - 1; i >= 0; i--)
148968ec77eSStephan Aßmus 				fControls.ItemAt(i)->Revert();
149968ec77eSStephan Aßmus 			break;
150968ec77eSStephan Aßmus 
151968ec77eSStephan Aßmus 		case M_SELECT:
152968ec77eSStephan Aßmus 			for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
153968ec77eSStephan Aßmus 				BTextView* text = fControls.ItemAt(i)->TextView();
154968ec77eSStephan Aßmus 				if (text->IsFocus()) {
155968ec77eSStephan Aßmus 					text->Select(0, text->TextLength());
156968ec77eSStephan Aßmus 					break;
157968ec77eSStephan Aßmus 				}
158968ec77eSStephan Aßmus 			}
159968ec77eSStephan Aßmus 			break;
160968ec77eSStephan Aßmus 
161968ec77eSStephan Aßmus 		case M_GROUP_MENU:
162968ec77eSStephan Aßmus 		{
163968ec77eSStephan Aßmus 			const char* name = NULL;
164968ec77eSStephan Aßmus 			if (msg->FindString("group", &name) == B_OK)
165968ec77eSStephan Aßmus 				SetAttribute(fCategoryAttribute, name, false);
166968ec77eSStephan Aßmus 			break;
167968ec77eSStephan Aßmus 		}
168968ec77eSStephan Aßmus 
169968ec77eSStephan Aßmus 	}
170968ec77eSStephan Aßmus }
171968ec77eSStephan Aßmus 
172968ec77eSStephan Aßmus 
173968ec77eSStephan Aßmus void
Draw(BRect updateRect)17484627497SPhilippe Houdoin PersonView::Draw(BRect updateRect)
17584627497SPhilippe Houdoin {
17684627497SPhilippe Houdoin 	if (!fPictureView)
17784627497SPhilippe Houdoin 		return;
17884627497SPhilippe Houdoin 
17984627497SPhilippe Houdoin 	// Draw a alert/get info-like strip
18084627497SPhilippe Houdoin 	BRect stripeRect = Bounds();
1810f5f1701SPhilippe Houdoin 	stripeRect.right = GridLayout()->HorizontalSpacing()
1820f5f1701SPhilippe Houdoin 		+ fPictureView->Bounds().Width() / 2;
18384627497SPhilippe Houdoin 	SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT));
18484627497SPhilippe Houdoin 	FillRect(stripeRect);
18584627497SPhilippe Houdoin }
18684627497SPhilippe Houdoin 
18784627497SPhilippe Houdoin 
18884627497SPhilippe Houdoin void
BuildGroupMenu()189968ec77eSStephan Aßmus PersonView::BuildGroupMenu()
190968ec77eSStephan Aßmus {
191fd44ef42SStephan Aßmus 	if (fGroups == NULL)
192fd44ef42SStephan Aßmus 		return;
193fd44ef42SStephan Aßmus 
194968ec77eSStephan Aßmus 	BMenuItem* item;
195968ec77eSStephan Aßmus 	while ((item = fGroups->ItemAt(0)) != NULL) {
196968ec77eSStephan Aßmus 		fGroups->RemoveItem(item);
197968ec77eSStephan Aßmus 		delete item;
198968ec77eSStephan Aßmus 	}
199968ec77eSStephan Aßmus 
200968ec77eSStephan Aßmus 	int32 count = 0;
201968ec77eSStephan Aßmus 
202968ec77eSStephan Aßmus 	BVolumeRoster volumeRoster;
203968ec77eSStephan Aßmus 	BVolume volume;
204968ec77eSStephan Aßmus 	while (volumeRoster.GetNextVolume(&volume) == B_OK) {
205968ec77eSStephan Aßmus 		BQuery query;
206968ec77eSStephan Aßmus 		query.SetVolume(&volume);
207968ec77eSStephan Aßmus 
208968ec77eSStephan Aßmus 		char buffer[256];
209968ec77eSStephan Aßmus 		snprintf(buffer, sizeof(buffer), "%s=*", fCategoryAttribute.String());
210968ec77eSStephan Aßmus 		query.SetPredicate(buffer);
211968ec77eSStephan Aßmus 		query.Fetch();
212968ec77eSStephan Aßmus 
213968ec77eSStephan Aßmus 		BEntry entry;
214968ec77eSStephan Aßmus 		while (query.GetNextEntry(&entry) == B_OK) {
215968ec77eSStephan Aßmus 			BFile file(&entry, B_READ_ONLY);
216968ec77eSStephan Aßmus 			attr_info info;
217968ec77eSStephan Aßmus 
218968ec77eSStephan Aßmus 			if (file.InitCheck() == B_OK
219968ec77eSStephan Aßmus 				&& file.GetAttrInfo(fCategoryAttribute, &info) == B_OK
220968ec77eSStephan Aßmus 				&& info.size > 1) {
22114b32de1SJérôme Duval 				if (info.size > (off_t)sizeof(buffer))
222968ec77eSStephan Aßmus 					info.size = sizeof(buffer);
223968ec77eSStephan Aßmus 
224968ec77eSStephan Aßmus 				if (file.ReadAttr(fCategoryAttribute.String(), B_STRING_TYPE,
225968ec77eSStephan Aßmus 						0, buffer, info.size) < 0) {
226968ec77eSStephan Aßmus 					continue;
227968ec77eSStephan Aßmus 				}
228968ec77eSStephan Aßmus 
229968ec77eSStephan Aßmus 				const char *text = buffer;
230968ec77eSStephan Aßmus 				while (true) {
231968ec77eSStephan Aßmus 					char* offset = strstr(text, ",");
232968ec77eSStephan Aßmus 					if (offset != NULL)
233968ec77eSStephan Aßmus 						offset[0] = '\0';
234968ec77eSStephan Aßmus 
235968ec77eSStephan Aßmus 					if (!fGroups->FindItem(text)) {
236968ec77eSStephan Aßmus 						int32 index = 0;
237968ec77eSStephan Aßmus 						while ((item = fGroups->ItemAt(index)) != NULL) {
238968ec77eSStephan Aßmus 							if (strcmp(text, item->Label()) < 0)
239968ec77eSStephan Aßmus 								break;
240968ec77eSStephan Aßmus 							index++;
241968ec77eSStephan Aßmus 						}
242968ec77eSStephan Aßmus 						BMessage* message = new BMessage(M_GROUP_MENU);
243968ec77eSStephan Aßmus 						message->AddString("group", text);
244968ec77eSStephan Aßmus 						fGroups->AddItem(new BMenuItem(text, message), index);
245968ec77eSStephan Aßmus 						count++;
246968ec77eSStephan Aßmus 					}
247968ec77eSStephan Aßmus 					if (offset) {
248968ec77eSStephan Aßmus 						text = offset + 1;
249968ec77eSStephan Aßmus 						while (*text == ' ')
250968ec77eSStephan Aßmus 							text++;
251968ec77eSStephan Aßmus 					}
252968ec77eSStephan Aßmus 					else
253968ec77eSStephan Aßmus 						break;
254968ec77eSStephan Aßmus 				}
255968ec77eSStephan Aßmus 			}
256968ec77eSStephan Aßmus 		}
257968ec77eSStephan Aßmus 	}
258968ec77eSStephan Aßmus 
259968ec77eSStephan Aßmus 	if (count == 0) {
260968ec77eSStephan Aßmus 		fGroups->AddItem(item = new BMenuItem(
261546208a5SOliver Tappe 			B_TRANSLATE_CONTEXT("none", "Groups list"),
262968ec77eSStephan Aßmus 			new BMessage(M_GROUP_MENU)));
263968ec77eSStephan Aßmus 		item->SetEnabled(false);
264968ec77eSStephan Aßmus 	}
265968ec77eSStephan Aßmus 
266968ec77eSStephan Aßmus 	fGroups->SetTargetForItems(this);
267968ec77eSStephan Aßmus }
268968ec77eSStephan Aßmus 
269968ec77eSStephan Aßmus 
270968ec77eSStephan Aßmus void
CreateFile(const entry_ref * ref)271968ec77eSStephan Aßmus PersonView::CreateFile(const entry_ref* ref)
272968ec77eSStephan Aßmus {
273a09c983cSPhilippe Saint-Pierre 	fRef = ref;
274968ec77eSStephan Aßmus 	Save();
275968ec77eSStephan Aßmus }
276968ec77eSStephan Aßmus 
277968ec77eSStephan Aßmus 
278968ec77eSStephan Aßmus bool
IsSaved() const279968ec77eSStephan Aßmus PersonView::IsSaved() const
280968ec77eSStephan Aßmus {
28184627497SPhilippe Houdoin 	if (fPictureView && fPictureView->HasChanged())
28284627497SPhilippe Houdoin 		return false;
28384627497SPhilippe Houdoin 
284968ec77eSStephan Aßmus 	for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
285968ec77eSStephan Aßmus 		if (fControls.ItemAt(i)->HasChanged())
286968ec77eSStephan Aßmus 			return false;
287968ec77eSStephan Aßmus 	}
288968ec77eSStephan Aßmus 
289968ec77eSStephan Aßmus 	return true;
290968ec77eSStephan Aßmus }
291968ec77eSStephan Aßmus 
292968ec77eSStephan Aßmus 
293968ec77eSStephan Aßmus void
Save()294968ec77eSStephan Aßmus PersonView::Save()
295968ec77eSStephan Aßmus {
29689d2bf3aSPhilippe Saint-Pierre 	BFile file(fRef, B_READ_WRITE);
29789d2bf3aSPhilippe Saint-Pierre 	if (file.InitCheck() != B_NO_ERROR)
298a09c983cSPhilippe Saint-Pierre 		return;
299a09c983cSPhilippe Saint-Pierre 
30089aa6cbeSPhilippe Houdoin 	fSaving = true;
30189aa6cbeSPhilippe Houdoin 
302968ec77eSStephan Aßmus 	int32 count = fControls.CountItems();
303968ec77eSStephan Aßmus 	for (int32 i = 0; i < count; i++) {
304968ec77eSStephan Aßmus 		AttributeTextControl* control = fControls.ItemAt(i);
305968ec77eSStephan Aßmus 		const char* value = control->Text();
30689d2bf3aSPhilippe Saint-Pierre 		file.WriteAttr(control->Attribute().String(), B_STRING_TYPE, 0,
307968ec77eSStephan Aßmus 			value, strlen(value) + 1);
308968ec77eSStephan Aßmus 		control->Update();
309968ec77eSStephan Aßmus 	}
31084627497SPhilippe Houdoin 
31184627497SPhilippe Houdoin 	// Write the picture, if any, in the person file content
31284627497SPhilippe Houdoin 	if (fPictureView) {
31389aa6cbeSPhilippe Houdoin 		// Trim any previous content
31489d2bf3aSPhilippe Saint-Pierre 		file.Seek(0, SEEK_SET);
31589d2bf3aSPhilippe Saint-Pierre 		file.SetSize(0);
31689aa6cbeSPhilippe Houdoin 
31789aa6cbeSPhilippe Houdoin 		BBitmap* picture = fPictureView->Bitmap();
31889aa6cbeSPhilippe Houdoin 		if (picture) {
31989aa6cbeSPhilippe Houdoin 			BBitmapStream stream(picture);
32089aa6cbeSPhilippe Houdoin 			// Detach *our* bitmap from stream to avoid its deletion
32189aa6cbeSPhilippe Houdoin 			// at stream object destruction
32289aa6cbeSPhilippe Houdoin 			stream.DetachBitmap(&picture);
32389aa6cbeSPhilippe Houdoin 
32484627497SPhilippe Houdoin 			BTranslatorRoster* roster = BTranslatorRoster::Default();
32589d2bf3aSPhilippe Saint-Pierre 			roster->Translate(&stream, NULL, NULL, &file,
326f22fe14cSPhilippe Houdoin 				fPictureView->SuggestedType(), B_TRANSLATOR_BITMAP,
327f22fe14cSPhilippe Houdoin 				fPictureView->SuggestedMIMEType());
32889aa6cbeSPhilippe Houdoin 
32984627497SPhilippe Houdoin 		}
33089aa6cbeSPhilippe Houdoin 
33189aa6cbeSPhilippe Houdoin 		fPictureView->Update();
33284627497SPhilippe Houdoin 	}
33389aa6cbeSPhilippe Houdoin 
33489d2bf3aSPhilippe Saint-Pierre 	file.GetModificationTime(&fLastModificationTime);
33589aa6cbeSPhilippe Houdoin 
33689aa6cbeSPhilippe Houdoin 	fSaving = false;
337968ec77eSStephan Aßmus }
338968ec77eSStephan Aßmus 
339968ec77eSStephan Aßmus 
340968ec77eSStephan Aßmus const char*
AttributeValue(const char * attribute) const341968ec77eSStephan Aßmus PersonView::AttributeValue(const char* attribute) const
342968ec77eSStephan Aßmus {
343968ec77eSStephan Aßmus 	for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
344968ec77eSStephan Aßmus 		if (fControls.ItemAt(i)->Attribute() == attribute)
345968ec77eSStephan Aßmus 			return fControls.ItemAt(i)->Text();
346968ec77eSStephan Aßmus 	}
347968ec77eSStephan Aßmus 
348968ec77eSStephan Aßmus 	return "";
349968ec77eSStephan Aßmus }
350968ec77eSStephan Aßmus 
351968ec77eSStephan Aßmus 
352968ec77eSStephan Aßmus void
SetAttribute(const char * attribute,bool update)353968ec77eSStephan Aßmus PersonView::SetAttribute(const char* attribute, bool update)
354968ec77eSStephan Aßmus {
355968ec77eSStephan Aßmus 	char* value = NULL;
356968ec77eSStephan Aßmus 	attr_info info;
357a09c983cSPhilippe Saint-Pierre 	BFile* file = NULL;
358a09c983cSPhilippe Saint-Pierre 
359a09c983cSPhilippe Saint-Pierre 	if (fRef != NULL)
360a09c983cSPhilippe Saint-Pierre 		file = new(std::nothrow) BFile(fRef, B_READ_ONLY);
361a09c983cSPhilippe Saint-Pierre 
362a09c983cSPhilippe Saint-Pierre 	if (file != NULL && file->GetAttrInfo(attribute, &info) == B_OK) {
363968ec77eSStephan Aßmus 		value = (char*)calloc(info.size, 1);
364a09c983cSPhilippe Saint-Pierre 		file->ReadAttr(attribute, B_STRING_TYPE, 0, value, info.size);
365968ec77eSStephan Aßmus 	}
366968ec77eSStephan Aßmus 
367968ec77eSStephan Aßmus 	SetAttribute(attribute, value, update);
368968ec77eSStephan Aßmus 
369968ec77eSStephan Aßmus 	free(value);
370a09c983cSPhilippe Saint-Pierre 	delete file;
371968ec77eSStephan Aßmus }
372968ec77eSStephan Aßmus 
373968ec77eSStephan Aßmus 
374968ec77eSStephan Aßmus void
SetAttribute(const char * attribute,const char * value,bool update)375968ec77eSStephan Aßmus PersonView::SetAttribute(const char* attribute, const char* value,
376968ec77eSStephan Aßmus 	bool update)
377968ec77eSStephan Aßmus {
378968ec77eSStephan Aßmus 	if (!LockLooper())
379968ec77eSStephan Aßmus 		return;
380968ec77eSStephan Aßmus 
381968ec77eSStephan Aßmus 	AttributeTextControl* control = NULL;
382968ec77eSStephan Aßmus 	for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
383968ec77eSStephan Aßmus 		if (fControls.ItemAt(i)->Attribute() == attribute) {
384968ec77eSStephan Aßmus 			control = fControls.ItemAt(i);
385968ec77eSStephan Aßmus 			break;
386968ec77eSStephan Aßmus 		}
387968ec77eSStephan Aßmus 	}
388968ec77eSStephan Aßmus 
389*964b6e80SHumdinger 	if (control == NULL) {
390*964b6e80SHumdinger 		UnlockLooper();
391968ec77eSStephan Aßmus 		return;
392*964b6e80SHumdinger 	}
393968ec77eSStephan Aßmus 
394968ec77eSStephan Aßmus 	if (update) {
395968ec77eSStephan Aßmus 		control->SetText(value);
396968ec77eSStephan Aßmus 		control->Update();
397968ec77eSStephan Aßmus 	} else {
398968ec77eSStephan Aßmus 		BTextView* text = control->TextView();
399968ec77eSStephan Aßmus 
400968ec77eSStephan Aßmus 		int32 start, end;
401968ec77eSStephan Aßmus 		text->GetSelection(&start, &end);
402968ec77eSStephan Aßmus 		if (start != end) {
403968ec77eSStephan Aßmus 			text->Delete();
404968ec77eSStephan Aßmus 			text->Insert(value);
405968ec77eSStephan Aßmus 		} else if ((end = text->TextLength())) {
406968ec77eSStephan Aßmus 			text->Select(end, end);
407968ec77eSStephan Aßmus 			text->Insert(",");
408968ec77eSStephan Aßmus 			text->Insert(value);
409968ec77eSStephan Aßmus 			text->Select(text->TextLength(), text->TextLength());
410968ec77eSStephan Aßmus 		} else
411968ec77eSStephan Aßmus 			control->SetText(value);
412968ec77eSStephan Aßmus 	}
413968ec77eSStephan Aßmus 
414968ec77eSStephan Aßmus 	UnlockLooper();
415968ec77eSStephan Aßmus }
416968ec77eSStephan Aßmus 
417968ec77eSStephan Aßmus 
41884627497SPhilippe Houdoin void
UpdatePicture(const entry_ref * ref)41984627497SPhilippe Houdoin PersonView::UpdatePicture(const entry_ref* ref)
42084627497SPhilippe Houdoin {
42189aa6cbeSPhilippe Houdoin 	if (fPictureView == NULL)
42289aa6cbeSPhilippe Houdoin 		return;
42389aa6cbeSPhilippe Houdoin 
42489aa6cbeSPhilippe Houdoin 	if (fSaving)
42589aa6cbeSPhilippe Houdoin 		return;
42689aa6cbeSPhilippe Houdoin 
42789aa6cbeSPhilippe Houdoin 	time_t modificationTime = 0;
42889aa6cbeSPhilippe Houdoin 	BEntry entry(ref);
42989aa6cbeSPhilippe Houdoin 	entry.GetModificationTime(&modificationTime);
43089aa6cbeSPhilippe Houdoin 
43189aa6cbeSPhilippe Houdoin 	if (entry.InitCheck() == B_OK
43289aa6cbeSPhilippe Houdoin 		&& modificationTime <= fLastModificationTime) {
43389aa6cbeSPhilippe Houdoin 		return;
43489aa6cbeSPhilippe Houdoin 	}
43589aa6cbeSPhilippe Houdoin 
43684627497SPhilippe Houdoin 	fPictureView->Update(ref);
43784627497SPhilippe Houdoin }
43884627497SPhilippe Houdoin 
43984627497SPhilippe Houdoin 
440968ec77eSStephan Aßmus bool
IsTextSelected() const441968ec77eSStephan Aßmus PersonView::IsTextSelected() const
442968ec77eSStephan Aßmus {
443968ec77eSStephan Aßmus 	for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
444968ec77eSStephan Aßmus 		BTextView* text = fControls.ItemAt(i)->TextView();
445968ec77eSStephan Aßmus 
446968ec77eSStephan Aßmus 		int32 start, end;
447968ec77eSStephan Aßmus 		text->GetSelection(&start, &end);
448968ec77eSStephan Aßmus 		if (start != end)
449968ec77eSStephan Aßmus 			return true;
450968ec77eSStephan Aßmus 	}
451968ec77eSStephan Aßmus 	return false;
452968ec77eSStephan Aßmus }
453