1faef1e54Sshatty/*
2bb5f99a5SStephan Aßmus * Copyright 2010, Haiku, Inc. All rights reserved.
3bb5f99a5SStephan Aßmus * Distributed under the terms of the MIT license.
4bb5f99a5SStephan Aßmus *
5bb5f99a5SStephan Aßmus * Authors:
6bb5f99a5SStephan Aßmus *		Robert Polic
7bb5f99a5SStephan Aßmus *		Stephan A��mus <superstippi@gmx.de>
8bb5f99a5SStephan Aßmus *
9bb5f99a5SStephan Aßmus * Copyright 1999, Be Incorporated.   All Rights Reserved.
10bb5f99a5SStephan Aßmus * This file may be used under the terms of the Be Sample Code License.
11bb5f99a5SStephan Aßmus */
12bb5f99a5SStephan Aßmus
13faef1e54Sshatty
14968ec77eSStephan Aßmus#include "PersonView.h"
157d90a09aSAlex Wilson
167d90a09aSAlex Wilson#include <stdio.h>
177d90a09aSAlex Wilson#include <stdlib.h>
187d90a09aSAlex Wilson#include <string.h>
197d90a09aSAlex Wilson
2084627497SPhilippe Houdoin#include <BitmapStream.h>
2154526b15SAdrien Destugues#include <Catalog.h>
22faef1e54Sshatty#include <fs_attr.h>
23faef1e54Sshatty#include <Box.h>
247d90a09aSAlex Wilson#include <ControlLook.h>
257d90a09aSAlex Wilson#include <GridLayout.h>
2654526b15SAdrien Destugues#include <Locale.h>
27faef1e54Sshatty#include <MenuField.h>
28faef1e54Sshatty#include <MenuItem.h>
29faef1e54Sshatty#include <PopUpMenu.h>
30faef1e54Sshatty#include <Query.h>
3184627497SPhilippe Houdoin#include <TranslationUtils.h>
3284627497SPhilippe Houdoin#include <Translator.h>
33faef1e54Sshatty#include <VolumeRoster.h>
347d90a09aSAlex Wilson#include <Window.h>
35faef1e54Sshatty
36bb5f99a5SStephan Aßmus#include "AttributeTextControl.h"
3784627497SPhilippe Houdoin#include "PictureView.h"
38faef1e54Sshatty
39faef1e54Sshatty
40546208a5SOliver Tappe#undef B_TRANSLATION_CONTEXT
41546208a5SOliver Tappe#define B_TRANSLATION_CONTEXT "People"
4254526b15SAdrien Destugues
4354526b15SAdrien Destugues
44968ec77eSStephan AßmusPersonView::PersonView(const char* name, const char* categoryAttribute,
45bb5f99a5SStephan Aßmus		const entry_ref *ref)
467d90a09aSAlex Wilson	:
47bb5f99a5SStephan Aßmus	BGridView(),
4889aa6cbeSPhilippe Houdoin	fLastModificationTime(0),
49fd44ef42SStephan Aßmus	fGroups(NULL),
50bb5f99a5SStephan Aßmus	fControls(20, false),
5184627497SPhilippe Houdoin	fCategoryAttribute(categoryAttribute),
5289aa6cbeSPhilippe Houdoin	fPictureView(NULL),
5389aa6cbeSPhilippe Houdoin	fSaving(false)
54faef1e54Sshatty{
557d90a09aSAlex Wilson	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);
62bb5f99a5SStephan 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;
78faef1e54Sshatty}
79faef1e54Sshatty
80faef1e54Sshatty
81968ec77eSStephan AßmusPersonView::~PersonView()
82faef1e54Sshatty{
83faef1e54Sshatty}
84faef1e54Sshatty
85faef1e54Sshatty
86779f323dSAxel Dörflervoid
87968ec77eSStephan AßmusPersonView::AddAttribute(const char* label, const char* attribute)
88faef1e54Sshatty{
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	}
96779f323dSAxel Dörfler
9784627497SPhilippe Houdoin	control = new AttributeTextControl(label, attribute);
98bb5f99a5SStephan Aßmus	fControls.AddItem(control);
99779f323dSAxel Dörfler
100bb5f99a5SStephan Aßmus	BGridLayout* layout = GridLayout();
10184627497SPhilippe Houdoin	int32 row = fControls.CountItems();
102779f323dSAxel Dörfler
103bb5f99a5SStephan Aßmus	if (fCategoryAttribute == attribute) {
104bb5f99a5SStephan Aßmus		// Special case the category attribute. The Group popup field will
105bb5f99a5SStephan Aßmus		// be added as the label instead.
106bb5f99a5SStephan Aßmus		fGroups = new BPopUpMenu(label);
107bb5f99a5SStephan Aßmus		fGroups->SetRadioMode(false);
108bb5f99a5SStephan Aßmus		BuildGroupMenu();
109779f323dSAxel Dörfler
110bb5f99a5SStephan Aßmus		BMenuField* field = new BMenuField("", "", fGroups);
111bb5f99a5SStephan Aßmus		field->SetEnabled(true);
11284627497SPhilippe Houdoin		layout->AddView(field, 1, row);
113bb5f99a5SStephan Aßmus
114bb5f99a5SStephan Aßmus		control->SetLabel("");
11584627497SPhilippe Houdoin		layout->AddView(control, 2, row);
116bb5f99a5SStephan Aßmus	} else {
11784627497SPhilippe Houdoin		layout->AddItem(control->CreateLabelLayoutItem(), 1, row);
11884627497SPhilippe Houdoin		layout->AddItem(control->CreateTextViewLayoutItem(), 2, row);
1197d90a09aSAlex Wilson	}
120779f323dSAxel Dörfler
121bb5f99a5SStephan Aßmus	SetAttribute(attribute, true);
122bb5f99a5SStephan Aßmus}
123faef1e54Sshatty
124bb5f99a5SStephan Aßmus
125bb5f99a5SStephan Aßmusvoid
126968ec77eSStephan AßmusPersonView::MakeFocus(bool focus)
127bb5f99a5SStephan Aßmus{
128bb5f99a5SStephan Aßmus	if (focus && fControls.CountItems() > 0)
129bb5f99a5SStephan Aßmus		fControls.ItemAt(0)->MakeFocus();
130bb5f99a5SStephan Aßmus	else
131bb5f99a5SStephan Aßmus		BView::MakeFocus(focus);
132faef1e54Sshatty}
133faef1e54Sshatty
134faef1e54Sshatty
135779f323dSAxel Dörflervoid
136968ec77eSStephan AßmusPersonView::MessageReceived(BMessage* msg)
137faef1e54Sshatty{
138faef1e54Sshatty	switch (msg->what) {
139faef1e54Sshatty		case M_SAVE:
140faef1e54Sshatty			Save();
141faef1e54Sshatty			break;
142faef1e54Sshatty
143faef1e54Sshatty		case M_REVERT:
14484627497SPhilippe Houdoin			if (fPictureView)
14584627497SPhilippe Houdoin				fPictureView->Revert();
14684627497SPhilippe Houdoin
147bb5f99a5SStephan Aßmus			for (int32 i = fControls.CountItems() - 1; i >= 0; i--)
148bb5f99a5SStephan Aßmus				fControls.ItemAt(i)->Revert();
149faef1e54Sshatty			break;
150faef1e54Sshatty
151faef1e54Sshatty		case M_SELECT:
152bb5f99a5SStephan Aßmus			for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
153bb5f99a5SStephan Aßmus				BTextView* text = fControls.ItemAt(i)->TextView();
154faef1e54Sshatty				if (text->IsFocus()) {
155faef1e54Sshatty					text->Select(0, text->TextLength());
156faef1e54Sshatty					break;
157faef1e54Sshatty				}
158faef1e54Sshatty			}
159bb5f99a5SStephan Aßmus			break;
160bb5f99a5SStephan Aßmus
161bb5f99a5SStephan Aßmus		case M_GROUP_MENU:
162bb5f99a5SStephan Aßmus		{
163bb5f99a5SStephan Aßmus			const char* name = NULL;
164bb5f99a5SStephan Aßmus			if (msg->FindString("group", &name) == B_OK)
165bb5f99a5SStephan Aßmus				SetAttribute(fCategoryAttribute, name, false);
166bb5f99a5SStephan Aßmus			break;
167bb5f99a5SStephan Aßmus		}
168bb5f99a5SStephan Aßmus
169faef1e54Sshatty	}
170faef1e54Sshatty}
171faef1e54Sshatty
172faef1e54Sshatty
17384627497SPhilippe Houdoinvoid
17484627497SPhilippe HoudoinPersonView::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
188779f323dSAxel Dörflervoid
189968ec77eSStephan AßmusPersonView::BuildGroupMenu()
190faef1e54Sshatty{
191fd44ef42SStephan Aßmus	if (fGroups == NULL)
192fd44ef42SStephan Aßmus		return;
193fd44ef42SStephan Aßmus
194779f323dSAxel Dörfler	BMenuItem* item;
195779f323dSAxel Dörfler	while ((item = fGroups->ItemAt(0)) != NULL) {
196faef1e54Sshatty		fGroups->RemoveItem(item);
197faef1e54Sshatty		delete item;
198faef1e54Sshatty	}
199faef1e54Sshatty
200779f323dSAxel Dörfler	int32 count = 0;
201779f323dSAxel Dörfler
202779f323dSAxel Dörfler	BVolumeRoster volumeRoster;
203779f323dSAxel Dörfler	BVolume volume;
204779f323dSAxel Dörfler	while (volumeRoster.GetNextVolume(&volume) == B_OK) {
205779f323dSAxel Dörfler		BQuery query;
206779f323dSAxel Dörfler		query.SetVolume(&volume);
207779f323dSAxel Dörfler
208779f323dSAxel Dörfler		char buffer[256];
209bb5f99a5SStephan Aßmus		snprintf(buffer, sizeof(buffer), "%s=*", fCategoryAttribute.String());
210779f323dSAxel Dörfler		query.SetPredicate(buffer);
211779f323dSAxel Dörfler		query.Fetch();
212779f323dSAxel Dörfler
213779f323dSAxel Dörfler		BEntry entry;
214779f323dSAxel Dörfler		while (query.GetNextEntry(&entry) == B_OK) {
215779f323dSAxel Dörfler			BFile file(&entry, B_READ_ONLY);
216779f323dSAxel Dörfler			attr_info info;
217779f323dSAxel Dörfler
218779f323dSAxel Dörfler			if (file.InitCheck() == B_OK
219bb5f99a5SStephan Aßmus				&& file.GetAttrInfo(fCategoryAttribute, &info) == B_OK
220779f323dSAxel Dörfler				&& info.size > 1) {
22114b32de1SJérôme Duval				if (info.size > (off_t)sizeof(buffer))
222779f323dSAxel Dörfler					info.size = sizeof(buffer);
223779f323dSAxel Dörfler
224bb5f99a5SStephan Aßmus				if (file.ReadAttr(fCategoryAttribute.String(), B_STRING_TYPE,
225bb5f99a5SStephan Aßmus						0, buffer, info.size) < 0) {
226779f323dSAxel Dörfler					continue;
227bb5f99a5SStephan Aßmus				}
228779f323dSAxel Dörfler
229779f323dSAxel Dörfler				const char *text = buffer;
230779f323dSAxel Dörfler				while (true) {
231779f323dSAxel Dörfler					char* offset = strstr(text, ",");
232779f323dSAxel Dörfler					if (offset != NULL)
233779f323dSAxel Dörfler						offset[0] = '\0';
234779f323dSAxel Dörfler
235779f323dSAxel Dörfler					if (!fGroups->FindItem(text)) {
236779f323dSAxel Dörfler						int32 index = 0;
237779f323dSAxel Dörfler						while ((item = fGroups->ItemAt(index)) != NULL) {
238779f323dSAxel Dörfler							if (strcmp(text, item->Label()) < 0)
239779f323dSAxel Dörfler								break;
240779f323dSAxel Dörfler							index++;
241779f323dSAxel Dörfler						}
242779f323dSAxel Dörfler						BMessage* message = new BMessage(M_GROUP_MENU);
243779f323dSAxel Dörfler						message->AddString("group", text);
244779f323dSAxel Dörfler						fGroups->AddItem(new BMenuItem(text, message), index);
245779f323dSAxel Dörfler						count++;
246faef1e54Sshatty					}
247779f323dSAxel Dörfler					if (offset) {
248779f323dSAxel Dörfler						text = offset + 1;
249779f323dSAxel Dörfler						while (*text == ' ')
250779f323dSAxel Dörfler							text++;
251779f323dSAxel Dörfler					}
252779f323dSAxel Dörfler					else
253779f323dSAxel Dörfler						break;
254faef1e54Sshatty				}
255faef1e54Sshatty			}
256faef1e54Sshatty		}
257faef1e54Sshatty	}
258faef1e54Sshatty
259bb5f99a5SStephan Aßmus	if (count == 0) {
26054526b15SAdrien Destugues		fGroups->AddItem(item = new BMenuItem(
261546208a5SOliver Tappe			B_TRANSLATE_CONTEXT("none", "Groups list"),
26254526b15SAdrien Destugues			new BMessage(M_GROUP_MENU)));
263779f323dSAxel Dörfler		item->SetEnabled(false);
264faef1e54Sshatty	}
265bb5f99a5SStephan Aßmus
266bb5f99a5SStephan Aßmus	fGroups->SetTargetForItems(this);
267faef1e54Sshatty}
268faef1e54Sshatty
269faef1e54Sshatty
270bb5f99a5SStephan Aßmusvoid
271968ec77eSStephan AßmusPersonView::CreateFile(const entry_ref* ref)
272faef1e54Sshatty{
273a09c983cSPhilippe Saint-Pierre	fRef = ref;
274bb5f99a5SStephan Aßmus	Save();
275faef1e54Sshatty}
276faef1e54Sshatty
277faef1e54Sshatty
278bb5f99a5SStephan Aßmusbool
279968ec77eSStephan AßmusPersonView::IsSaved() const
280faef1e54Sshatty{
28184627497SPhilippe Houdoin	if (fPictureView && fPictureView->HasChanged())
28284627497SPhilippe Houdoin		return false;
28384627497SPhilippe Houdoin
284bb5f99a5SStephan Aßmus	for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
285bb5f99a5SStephan Aßmus		if (fControls.ItemAt(i)->HasChanged())
286bb5f99a5SStephan Aßmus			return false;
287bb5f99a5SStephan Aßmus	}
288779f323dSAxel Dörfler
289bb5f99a5SStephan Aßmus	return true;
290faef1e54Sshatty}
291faef1e54Sshatty
292faef1e54Sshatty
293779f323dSAxel Dörflervoid
294968ec77eSStephan AßmusPersonView::Save()
295faef1e54Sshatty{
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
302bb5f99a5SStephan Aßmus	int32 count = fControls.CountItems();
303bb5f99a5SStephan Aßmus	for (int32 i = 0; i < count; i++) {
304bb5f99a5SStephan Aßmus		AttributeTextControl* control = fControls.ItemAt(i);
305bb5f99a5SStephan Aßmus		const char* value = control->Text();
30689d2bf3aSPhilippe Saint-Pierre		file.WriteAttr(control->Attribute().String(), B_STRING_TYPE, 0,
307bb5f99a5SStephan Aßmus			value, strlen(value) + 1);
308bb5f99a5SStephan Aßmus		control->Update();
309bb5f99a5SStephan 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;
337faef1e54Sshatty}
338faef1e54Sshatty
339faef1e54Sshatty
340bb5f99a5SStephan Aßmusconst char*
341968ec77eSStephan AßmusPersonView::AttributeValue(const char* attribute) const
342faef1e54Sshatty{
343bb5f99a5SStephan Aßmus	for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
344bb5f99a5SStephan Aßmus		if (fControls.ItemAt(i)->Attribute() == attribute)
345bb5f99a5SStephan Aßmus			return fControls.ItemAt(i)->Text();
346779f323dSAxel Dörfler	}
34784627497SPhilippe Houdoin
348bb5f99a5SStephan Aßmus	return "";
349faef1e54Sshatty}
350faef1e54Sshatty
351faef1e54Sshatty
352a7291500SBruno G. Albuquerquevoid
353968ec77eSStephan AßmusPersonView::SetAttribute(const char* attribute, bool update)
354a7291500SBruno G. Albuquerque{
355bb5f99a5SStephan Aßmus	char* value = NULL;
356a7291500SBruno G. Albuquerque	attr_info info;
357d0ac6099SHumdinger	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) {
363bb5f99a5SStephan Aßmus		value = (char*)calloc(info.size, 1);
364a09c983cSPhilippe Saint-Pierre		file->ReadAttr(attribute, B_STRING_TYPE, 0, value, info.size);
365a7291500SBruno G. Albuquerque	}
366a7291500SBruno G. Albuquerque
367bb5f99a5SStephan Aßmus	SetAttribute(attribute, value, update);
368bb5f99a5SStephan Aßmus
369bb5f99a5SStephan Aßmus	free(value);
370a09c983cSPhilippe Saint-Pierre	delete file;
371a7291500SBruno G. Albuquerque}
372a7291500SBruno G. Albuquerque
373a7291500SBruno G. Albuquerque
374779f323dSAxel Dörflervoid
375968ec77eSStephan AßmusPersonView::SetAttribute(const char* attribute, const char* value,
376bb5f99a5SStephan Aßmus	bool update)
377faef1e54Sshatty{
378bb5f99a5SStephan Aßmus	if (!LockLooper())
379bb5f99a5SStephan Aßmus		return;
380bb5f99a5SStephan Aßmus
381bb5f99a5SStephan Aßmus	AttributeTextControl* control = NULL;
382bb5f99a5SStephan Aßmus	for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
383bb5f99a5SStephan Aßmus		if (fControls.ItemAt(i)->Attribute() == attribute) {
384bb5f99a5SStephan Aßmus			control = fControls.ItemAt(i);
385bb5f99a5SStephan Aßmus			break;
386bb5f99a5SStephan Aßmus		}
387bb5f99a5SStephan Aßmus	}
388bb5f99a5SStephan Aßmus
389bb5f99a5SStephan Aßmus	if (control == NULL)
390bb5f99a5SStephan Aßmus		return;
391779f323dSAxel Dörfler
392faef1e54Sshatty	if (update) {
393bb5f99a5SStephan Aßmus		control->SetText(value);
394bb5f99a5SStephan Aßmus		control->Update();
395779f323dSAxel Dörfler	} else {
396bb5f99a5SStephan Aßmus		BTextView* text = control->TextView();
397779f323dSAxel Dörfler
398779f323dSAxel Dörfler		int32 start, end;
399faef1e54Sshatty		text->GetSelection(&start, &end);
400faef1e54Sshatty		if (start != end) {
401faef1e54Sshatty			text->Delete();
402bb5f99a5SStephan Aßmus			text->Insert(value);
403779f323dSAxel Dörfler		} else if ((end = text->TextLength())) {
404faef1e54Sshatty			text->Select(end, end);
405faef1e54Sshatty			text->Insert(",");
406bb5f99a5SStephan Aßmus			text->Insert(value);
407faef1e54Sshatty			text->Select(text->TextLength(), text->TextLength());
408779f323dSAxel Dörfler		} else
409bb5f99a5SStephan Aßmus			control->SetText(value);
410faef1e54Sshatty	}
411779f323dSAxel Dörfler
412bb5f99a5SStephan Aßmus	UnlockLooper();
413faef1e54Sshatty}
414faef1e54Sshatty
415faef1e54Sshatty
41684627497SPhilippe Houdoinvoid
41784627497SPhilippe HoudoinPersonView::UpdatePicture(const entry_ref* ref)
41884627497SPhilippe Houdoin{
41989aa6cbeSPhilippe Houdoin	if (fPictureView == NULL)
42089aa6cbeSPhilippe Houdoin		return;
42189aa6cbeSPhilippe Houdoin
42289aa6cbeSPhilippe Houdoin	if (fSaving)
42389aa6cbeSPhilippe Houdoin		return;
42489aa6cbeSPhilippe Houdoin
42589aa6cbeSPhilippe Houdoin	time_t modificationTime = 0;
42689aa6cbeSPhilippe Houdoin	BEntry entry(ref);
42789aa6cbeSPhilippe Houdoin	entry.GetModificationTime(&modificationTime);
42889aa6cbeSPhilippe Houdoin
42989aa6cbeSPhilippe Houdoin	if (entry.InitCheck() == B_OK
43089aa6cbeSPhilippe Houdoin		&& modificationTime <= fLastModificationTime) {
43189aa6cbeSPhilippe Houdoin		return;
43289aa6cbeSPhilippe Houdoin	}
43389aa6cbeSPhilippe Houdoin
43489aa6cbeSPhilippe Houdoin	fPictureView->Update(ref);
43584627497SPhilippe Houdoin}
43684627497SPhilippe Houdoin
43784627497SPhilippe Houdoin
438779f323dSAxel Dörflerbool
439968ec77eSStephan AßmusPersonView::IsTextSelected() const
440faef1e54Sshatty{
441bb5f99a5SStephan Aßmus	for (int32 i = fControls.CountItems() - 1; i >= 0; i--) {
442bb5f99a5SStephan Aßmus		BTextView* text = fControls.ItemAt(i)->TextView();
443faef1e54Sshatty
444779f323dSAxel Dörfler		int32 start, end;
445faef1e54Sshatty		text->GetSelection(&start, &end);
446faef1e54Sshatty		if (start != end)
447779f323dSAxel Dörfler			return true;
448faef1e54Sshatty	}
449779f323dSAxel Dörfler	return false;
450faef1e54Sshatty}
451