View Javadoc
1   package org.argeo.people.e4.parts;
2   
3   import javax.jcr.Node;
4   import javax.jcr.NodeIterator;
5   import javax.jcr.Property;
6   import javax.jcr.PropertyType;
7   import javax.jcr.RepositoryException;
8   
9   import org.argeo.cms.ui.eclipse.forms.AbstractFormPart;
10  import org.argeo.cms.ui.eclipse.forms.FormToolkit;
11  import org.argeo.cms.util.CmsUtils;
12  import org.argeo.cms.widgets.ScrolledPage;
13  import org.argeo.connect.ConnectConstants;
14  import org.argeo.connect.resources.ResourcesService;
15  import org.argeo.connect.ui.ConnectEditor;
16  import org.argeo.connect.ui.ConnectUiStyles;
17  import org.argeo.connect.ui.ConnectUiUtils;
18  import org.argeo.connect.ui.ConnectWorkbenchUtils;
19  import org.argeo.connect.ui.SystemWorkbenchService;
20  import org.argeo.connect.ui.util.LazyCTabControl;
21  import org.argeo.connect.ui.widgets.TagLikeDropDown;
22  import org.argeo.connect.util.ConnectJcrUtils;
23  import org.argeo.eclipse.ui.EclipseUiUtils;
24  import org.argeo.jcr.JcrUtils;
25  import org.argeo.people.ContactService;
26  import org.argeo.people.ContactValueCatalogs;
27  import org.argeo.people.PeopleException;
28  import org.argeo.people.PeopleNames;
29  import org.argeo.people.PeopleService;
30  import org.argeo.people.PeopleTypes;
31  import org.argeo.people.ui.PeopleMsg;
32  import org.argeo.people.ui.composites.ContactAddressComposite;
33  import org.argeo.people.ui.composites.ContactComposite;
34  import org.argeo.people.ui.dialogs.PickUpOrgDialog;
35  import org.argeo.people.util.PeopleJcrUtils;
36  import org.eclipse.swt.SWT;
37  import org.eclipse.swt.events.SelectionAdapter;
38  import org.eclipse.swt.events.SelectionEvent;
39  import org.eclipse.swt.events.TraverseEvent;
40  import org.eclipse.swt.events.TraverseListener;
41  import org.eclipse.swt.layout.GridData;
42  import org.eclipse.swt.layout.GridLayout;
43  import org.eclipse.swt.layout.RowData;
44  import org.eclipse.swt.layout.RowLayout;
45  import org.eclipse.swt.widgets.Button;
46  import org.eclipse.swt.widgets.Combo;
47  import org.eclipse.swt.widgets.Composite;
48  import org.eclipse.swt.widgets.Control;
49  import org.eclipse.swt.widgets.Label;
50  import org.eclipse.swt.widgets.Link;
51  import org.eclipse.swt.widgets.Text;
52  //import org.eclipse.ui.forms.AbstractFormPart;
53  //import org.eclipse.ui.forms.widgets.FormToolkit;
54  
55  /** A panel to display contacts */
56  public class ContactListCTab extends LazyCTabControl {
57  	private static final long serialVersionUID = 58381532068661087L;
58  
59  	// Context
60  	private final ResourcesService resourcesService;
61  	private final PeopleService peopleService;
62  	private final SystemWorkbenchService systemWorkbenchService;
63  	private final Node entity;
64  
65  	// UI Objects
66  	private final ConnectEditor editor;
67  	private final FormToolkit toolkit;
68  	private ContactFormPart myFormPart;
69  	private Composite innerCmp;
70  	// Caches the add new contact combo
71  	private Combo addContactCmb;
72  
73  	public ContactListCTab(Composite parent, int style, ConnectEditor editor, Node entityNode,
74  			ResourcesService resourcesService, PeopleService peopleService,
75  			SystemWorkbenchService systemWorkbenchService) {
76  		super(parent, style);
77  		this.editor = editor;
78  		this.toolkit = editor.getFormToolkit();
79  		this.entity = entityNode;
80  		this.resourcesService = resourcesService;
81  		this.peopleService = peopleService;
82  		this.systemWorkbenchService = systemWorkbenchService;
83  	}
84  
85  	@Override
86  	public void refreshPartControl() {
87  		myFormPart.refresh();
88  		layout(true, true);
89  	}
90  
91  	@Override
92  	public void createPartControl(Composite parent) {
93  		parent.setLayout(new GridLayout());
94  		ScrolledPage scrolled = new ScrolledPage(this, SWT.NO_FOCUS);
95  		scrolled.setLayoutData(EclipseUiUtils.fillAll());
96  		scrolled.setLayout(EclipseUiUtils.noSpaceGridLayout());
97  		innerCmp = new Composite(scrolled, SWT.NO_FOCUS);
98  		innerCmp.setLayoutData(EclipseUiUtils.fillAll());
99  		innerCmp.setLayout(EclipseUiUtils.noSpaceGridLayout());
100 
101 		myFormPart = new ContactFormPart();
102 		myFormPart.initialize(editor.getManagedForm());
103 		editor.getManagedForm().addPart(myFormPart);
104 	}
105 
106 	private class ContactFormPart extends AbstractFormPart {
107 
108 		@Override
109 		public void refresh() {
110 			super.refresh();
111 			try {
112 				if (innerCmp.isDisposed())
113 					return;
114 
115 				// We redraw the full part at each refresh
116 				CmsUtils.clear(innerCmp);
117 
118 				boolean checkedOut = editor.isEditing();
119 				GridData gd;
120 				Composite newContactCmp = null;
121 
122 				// Add contact tool bar.
123 				if (checkedOut) {
124 					newContactCmp = toolkit.createComposite(innerCmp, SWT.NO_FOCUS);
125 					newContactCmp.setLayoutData(EclipseUiUtils.fillWidth());
126 					populateAddContactPanel(newContactCmp);
127 				}
128 
129 				// list existing contacts
130 				Composite contactListCmp = toolkit.createComposite(innerCmp, SWT.NO_FOCUS);
131 
132 				gd = new GridData(SWT.FILL, SWT.FILL, true, true);
133 				if (checkedOut) {
134 					long count = getCurrentContactCount();
135 					if (count < 5)
136 						gd.heightHint = 170;
137 					else
138 						gd.heightHint = (int) (count * 30 + 20);
139 
140 				}
141 				contactListCmp.setLayoutData(gd);
142 
143 				populateDisplayContactPanel(contactListCmp, checkedOut);
144 				contactListCmp.layout(true);
145 
146 				// notes about current contact
147 				Composite noteCmp = toolkit.createComposite(innerCmp, SWT.NO_FOCUS);
148 				gd = new GridData(SWT.FILL, SWT.BOTTOM, true, false);
149 				gd.heightHint = 100;
150 				noteCmp.setLayoutData(gd);
151 				populateNotePanel(noteCmp);
152 
153 				// innerCmp.pack(true);
154 				// innerCmp.setLayoutData(gd = new GridData(SWT.FILL, SWT.FILL,
155 				// true, true));
156 				// innerCmp.layout();
157 				// innerCmp.getParent().pack(true);
158 				// innerCmp.getParent().layout(true, true);
159 				ContactListCTab.this.layout(true, true);
160 			} catch (Exception e) {
161 				throw new PeopleException("Unexpected error while refreshing node " + entity, e);
162 			}
163 		}
164 	}
165 
166 	private long getCurrentContactCount() {
167 		long result = 0;
168 		try {
169 			if (entity.hasNode(PeopleNames.PEOPLE_CONTACTS)) {
170 				Node contactsPar = entity.getNode(PeopleNames.PEOPLE_CONTACTS);
171 				NodeIterator ni = contactsPar.getNodes();
172 				result = ni.getSize();
173 			}
174 		} catch (RepositoryException re) {
175 			throw new PeopleException("Error while conting contacts for " + entity, re);
176 		}
177 		return result;
178 	}
179 
180 	/** Manage display and update of existing contact Nodes */
181 	private void populateDisplayContactPanel(final Composite parent, boolean isCheckedOut) {
182 		parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
183 		try {
184 			String[] knownTypes = peopleService.getContactService().getKnownContactTypes();
185 			if (entity.hasNode(PeopleNames.PEOPLE_CONTACTS)) {
186 				Node contactsPar = entity.getNode(PeopleNames.PEOPLE_CONTACTS);
187 
188 				for (String currType : knownTypes) {
189 					NodeIterator ni = contactsPar.getNodes();
190 					loop: while (ni.hasNext()) {
191 						Node currNode = ni.nextNode();
192 						if (!currNode.isNodeType(currType))
193 							continue loop;
194 						if (ConnectJcrUtils.isNodeType(currNode, PeopleTypes.PEOPLE_POSTAL_ADDRESS))
195 							new ContactAddressComposite(parent, SWT.NO_FOCUS, editor, myFormPart, resourcesService,
196 									peopleService, systemWorkbenchService, currNode, entity);
197 						else
198 							new ContactComposite(parent, SWT.NO_FOCUS, editor, myFormPart, currNode, entity,
199 									resourcesService, peopleService, systemWorkbenchService);
200 					}
201 				}
202 			}
203 		} catch (RepositoryException e) {
204 			throw new PeopleException("Cannot populate existing contact list for entity " + entity, e);
205 		}
206 	}
207 
208 	private void populateNotePanel(Composite parent) {
209 		parent.setLayout(ConnectUiUtils.noSpaceGridLayout(2));
210 		Label label = ConnectUiUtils.createBoldLabel(toolkit, parent, PeopleMsg.notes.lead() + ": ");
211 
212 		GridData gd = new GridData(SWT.RIGHT, SWT.TOP, false, false);
213 		gd.verticalIndent = 3;
214 		label.setLayoutData(gd);
215 
216 		Text notesTxt = toolkit.createText(parent, "", SWT.BORDER | SWT.MULTI | SWT.WRAP);
217 		notesTxt.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
218 		ConnectWorkbenchUtils.refreshFormTextWidget(editor, notesTxt, entity, Property.JCR_DESCRIPTION);
219 		ConnectWorkbenchUtils.addTxtModifyListener(myFormPart, notesTxt, entity, Property.JCR_DESCRIPTION,
220 				PropertyType.STRING);
221 	}
222 
223 	/** Populate a composite that enable addition of a new contact */
224 	private void populateAddContactPanel(Composite parent) {
225 		RowLayout layout = new RowLayout();
226 		layout.wrap = true;
227 		layout.marginTop = layout.marginBottom = 0;
228 		parent.setLayout(layout);
229 
230 		// ADD CONTACT
231 		addContactCmb = new Combo(parent, SWT.NONE | SWT.READ_ONLY | SWT.NO_FOCUS);
232 
233 		addContactCmb.setLayoutData(new RowData(140, SWT.DEFAULT));
234 		addContactCmb.setItems(ContactValueCatalogs.ARRAY_CONTACT_TYPES);
235 		addContactCmb.add(PeopleMsg.addAContact.lead(), 0);
236 		addContactCmb.select(0);
237 
238 		// NATURE(work or private) is only for persons
239 		Combo natureCmb = ConnectJcrUtils.isNodeType(entity, PeopleTypes.PEOPLE_PERSON)
240 				? new Combo(parent, SWT.READ_ONLY)
241 				: null;
242 		if (natureCmb != null) {
243 			natureCmb.setLayoutData(new RowData(100, SWT.DEFAULT));
244 			natureCmb.setItems(ContactValueCatalogs.ARRAY_CONTACT_NATURES);
245 			natureCmb.setVisible(false);
246 		}
247 
248 		// Listeners
249 		addContactCmb.addSelectionListener(new MySelectionAdapter(entity, parent, addContactCmb, natureCmb));
250 
251 		if (natureCmb != null) {
252 			natureCmb.addSelectionListener(new MySelectionAdapter(entity, parent, addContactCmb, natureCmb));
253 		}
254 	}
255 
256 	private class MySelectionAdapter extends SelectionAdapter {
257 		private static final long serialVersionUID = 1L;
258 		private final Node entity;
259 		private final Composite parent;
260 		private final Combo addContactCmb;
261 		private final Combo natureCmb;
262 
263 		public MySelectionAdapter(Node entity, Composite editPanel, Combo addContactCmb, Combo natureCmb) {
264 			this.entity = entity;
265 			this.parent = editPanel;
266 			this.addContactCmb = addContactCmb;
267 			this.natureCmb = natureCmb;
268 		}
269 
270 		@Override
271 		public void widgetSelected(SelectionEvent e) {
272 			try {
273 				int index = addContactCmb.getSelectionIndex();
274 				if (natureCmb != null) {
275 					natureCmb.setVisible(index > 0);
276 					if (index > 0 && natureCmb.getSelectionIndex() == -1)
277 						natureCmb.select(0);
278 				}
279 
280 				if (index == 0) {
281 					resetAddContactEditPanel(parent, addContactCmb, natureCmb);
282 				} else {
283 					String type = ContactValueCatalogs.getKeyByValue(ContactValueCatalogs.MAPS_CONTACT_TYPES,
284 							addContactCmb.getItem(index));
285 					String nature = null;
286 					int natureIndex = -1;
287 					if (natureCmb != null)
288 						natureIndex = natureCmb.getSelectionIndex();
289 					if (natureIndex != -1)
290 						nature = ContactValueCatalogs.ARRAY_CONTACT_NATURES[natureIndex];
291 
292 					removeOtherChildren(parent, addContactCmb, natureCmb);
293 
294 					Control first = populateNewContactComposite(parent, entity, type, nature, addContactCmb);
295 					if (first != null)
296 						first.setFocus();
297 				}
298 			} catch (RepositoryException e1) {
299 				throw new PeopleException("Unable to refresh add contact panel", e1);
300 			}
301 
302 			parent.layout(true, true);
303 			Control[] controls = new Control[1];
304 			controls[0] = parent;
305 			ContactListCTab.this.layout(controls);
306 		}
307 	}
308 
309 	private void removeOtherChildren(Composite editPanel, Combo chooseTypeCmb, Combo chooseNatureCmb) {
310 		// remove all controls
311 		for (Control ctl : editPanel.getChildren()) {
312 			if (!(chooseTypeCmb == ctl || chooseNatureCmb != null && chooseNatureCmb == ctl)) {
313 				// log.debug("Disposing control " + ctl.toString());
314 				ctl.dispose();
315 			}
316 		}
317 	}
318 
319 	private void resetAddContactEditPanel(Composite editPanel, Combo chooseTypeCmb, Combo chooseNatureCmb) {
320 		// reset combo
321 		if (chooseTypeCmb.getSelectionIndex() != 0)
322 			chooseTypeCmb.select(0);
323 		if (chooseNatureCmb != null)
324 			chooseNatureCmb.setVisible(false);
325 		removeOtherChildren(editPanel, chooseTypeCmb, chooseNatureCmb);
326 	}
327 
328 	/** Populate an editable contact composite */
329 	private Control populateNewContactComposite(Composite parent, Node entity, String contactType, String nature,
330 			Combo addContactCombo) throws RepositoryException {
331 
332 		boolean isPro = nature != null && nature.equals(ContactValueCatalogs.CONTACT_NATURE_PRO);
333 
334 		if (contactType.equals(PeopleTypes.PEOPLE_URL) || contactType.equals(PeopleTypes.PEOPLE_MAIL)) {
335 			return createMailWidgets(parent, entity, contactType, nature, addContactCombo);
336 		} else if (contactType.equals(PeopleTypes.PEOPLE_POSTAL_ADDRESS)) {
337 			if (isPro)
338 				return createWorkAddressWidgets(parent, addContactCombo, entity, contactType);
339 			else
340 				return createAddressWidgets(parent, addContactCombo, contactType, isPro);
341 		} else
342 			return createContactWidgets(parent, addContactCombo, contactType, isPro);
343 
344 	}
345 
346 	private Control createMailWidgets(Composite parent, Node entity, String contactType, final String nature,
347 			final Combo addContactCombo) {
348 
349 		final Text valueTxt = createRowDataLT(parent, PeopleMsg.contactValue.lead(), 200);
350 
351 		final Text labelTxt = createRowDataLT(parent, PeopleMsg.label.lead(), 120);
352 
353 		final Button primaryChk = toolkit.createButton(parent, PeopleMsg.primary.lead(), SWT.CHECK);
354 
355 		final Button validBtn = toolkit.createButton(parent, PeopleMsg.add.lead(), SWT.PUSH);
356 
357 		validBtn.addSelectionListener(new SelectionAdapter() {
358 			private static final long serialVersionUID = 1L;
359 
360 			@Override
361 			public void widgetSelected(SelectionEvent e) {
362 
363 				String value = valueTxt.getText();
364 				String label = labelTxt.getText();
365 				boolean isPrimary = primaryChk.getSelection();
366 				saveAndRefresh(contactType, JcrUtils.replaceInvalidChars(value), value, isPrimary, null, label);
367 			}
368 		});
369 
370 		TraverseListener travList = new TraverseListener() {
371 			private static final long serialVersionUID = 9192624317905937169L;
372 
373 			@Override
374 			public void keyTraversed(TraverseEvent e) {
375 				if (e.keyCode == SWT.CR) {
376 					e.doit = false;
377 					String value = valueTxt.getText();
378 					String label = labelTxt.getText();
379 					boolean isPrimary = primaryChk.getSelection();
380 					saveAndRefresh(contactType, JcrUtils.replaceInvalidChars(value), value, isPrimary, null, label);
381 				}
382 			}
383 		};
384 
385 		valueTxt.addTraverseListener(travList);
386 		labelTxt.addTraverseListener(travList);
387 		return valueTxt;
388 	}
389 
390 	private Control createContactWidgets(Composite parent, Combo addContactCombo, String contactType, boolean isPro)
391 			throws RepositoryException {
392 
393 		final Text valueTxt = createRowDataLT(parent, PeopleMsg.contactValue.lead(), 200);
394 
395 		final Combo catCmb = new Combo(parent, SWT.READ_ONLY);
396 		catCmb.setItems(peopleService.getContactService().getContactCategories(peopleService.getMainNodeType(entity),
397 				contactType, isPro));
398 		catCmb.select(0);
399 
400 		final Text labelTxt = createRowDataLT(parent, PeopleMsg.label.lead(), 120);
401 
402 		final Button primaryChk = toolkit.createButton(parent, PeopleMsg.primary.lead(), SWT.CHECK);
403 
404 		final Button validBtn = toolkit.createButton(parent, PeopleMsg.add.lead(), SWT.PUSH);
405 
406 		validBtn.addSelectionListener(new SelectionAdapter() {
407 			private static final long serialVersionUID = 1L;
408 
409 			@Override
410 			public void widgetSelected(SelectionEvent e) {
411 				String value = valueTxt.getText();
412 				String label = labelTxt.getText();
413 				String cat = catCmb.getText();
414 				boolean isPrimary = primaryChk.getSelection();
415 				saveAndRefresh(contactType, JcrUtils.replaceInvalidChars(value), value, isPrimary, cat, label);
416 			}
417 		});
418 
419 		TraverseListener travList = new TraverseListener() {
420 			private static final long serialVersionUID = 9192624317905937169L;
421 
422 			@Override
423 			public void keyTraversed(TraverseEvent e) {
424 				if (e.keyCode == SWT.CR) {
425 					e.doit = false;
426 					String value = valueTxt.getText();
427 					String label = labelTxt.getText();
428 					String cat = catCmb.getText();
429 					boolean isPrimary = primaryChk.getSelection();
430 					saveAndRefresh(contactType, JcrUtils.replaceInvalidChars(value), value, isPrimary, cat, label);
431 				}
432 			}
433 		};
434 
435 		valueTxt.addTraverseListener(travList);
436 		labelTxt.addTraverseListener(travList);
437 		catCmb.addTraverseListener(travList);
438 		return valueTxt;
439 	}
440 
441 	private void saveAndRefresh(String contactType, String name, String value, boolean isPrimary, String category,
442 			String label) {
443 
444 		PeopleJcrUtils.createContact(resourcesService, peopleService, entity, contactType, value, isPrimary, category,
445 				label);
446 		addContactCmb.select(0);
447 		myFormPart.markDirty();
448 		myFormPart.refresh();
449 	}
450 
451 	private Control createAddressWidgets(Composite parent, Combo addContactCombo, String contactType, boolean isPro) {
452 
453 		final Combo catCmb = new Combo(parent, SWT.NONE);
454 		ContactService contactService = peopleService.getContactService();
455 		String entityType = peopleService.getMainNodeType(entity);
456 		catCmb.setItems(contactService.getContactCategories(entityType, contactType, isPro));
457 		catCmb.select(0);
458 
459 		final Text streetTxt = createRowDataLT(parent, PeopleMsg.street.lead(), 150);
460 		final Text street2Txt = createRowDataLT(parent, PeopleMsg.streetComplement.lead(), 150);
461 		final Text zipTxt = createRowDataLT(parent, PeopleMsg.zipCode.lead(), 60);
462 		final Text cityTxt = createRowDataLT(parent, PeopleMsg.city.lead(), 150);
463 		final Text stateTxt = createRowDataLT(parent, PeopleMsg.state.lead(), 150);
464 		// Country: dropdown + text
465 		Text countryTxt = createRowDataLT(parent, PeopleMsg.country.lead(), 150);
466 		final TagLikeDropDown countryDD = new TagLikeDropDown(ConnectJcrUtils.getSession(entity), resourcesService,
467 				ConnectConstants.RESOURCE_COUNTRY, countryTxt);
468 		final Text geoPointTxt = createRowDataLT(parent, PeopleMsg.geopoint.lead(), 200);
469 		final Text labelTxt = createRowDataLT(parent, PeopleMsg.label.lead(), 120);
470 
471 		final Button primaryChk = toolkit.createButton(parent, PeopleMsg.primary.lead(), SWT.CHECK);
472 
473 		final Button validBtn = toolkit.createButton(parent, PeopleMsg.save.lead(), SWT.PUSH);
474 
475 		validBtn.addSelectionListener(new SelectionAdapter() {
476 
477 			private static final long serialVersionUID = 1L;
478 
479 			@Override
480 			public void widgetSelected(SelectionEvent e) {
481 				String cat = catCmb.getText();
482 				String label = labelTxt.getText();
483 				boolean isPrimary = primaryChk.getSelection();
484 
485 				PeopleJcrUtils.createAddress(resourcesService, peopleService, entity, streetTxt.getText(),
486 						street2Txt.getText(), zipTxt.getText(), cityTxt.getText(), stateTxt.getText(),
487 						countryDD.getText(), geoPointTxt.getText(), isPrimary, cat, label);
488 				myFormPart.markDirty();
489 				myFormPart.refresh();
490 			}
491 
492 		});
493 
494 		TraverseListener travList = new TraverseListener() {
495 			private static final long serialVersionUID = 9192624317905937169L;
496 
497 			@Override
498 			public void keyTraversed(TraverseEvent e) {
499 				if (e.keyCode == SWT.CR) {
500 					e.doit = false;
501 					String cat = catCmb.getText();
502 					String label = labelTxt.getText();
503 					boolean isPrimary = primaryChk.getSelection();
504 
505 					PeopleJcrUtils.createAddress(resourcesService, peopleService, entity, streetTxt.getText(),
506 							street2Txt.getText(), zipTxt.getText(), cityTxt.getText(), stateTxt.getText(),
507 							countryDD.getText(), geoPointTxt.getText(), isPrimary, cat, label);
508 					myFormPart.markDirty();
509 					myFormPart.refresh();
510 				}
511 			}
512 		};
513 
514 		streetTxt.addTraverseListener(travList);
515 		street2Txt.addTraverseListener(travList);
516 		zipTxt.addTraverseListener(travList);
517 		cityTxt.addTraverseListener(travList);
518 		stateTxt.addTraverseListener(travList);
519 		countryTxt.addTraverseListener(travList);
520 		geoPointTxt.addTraverseListener(travList);
521 		labelTxt.addTraverseListener(travList);
522 		catCmb.addTraverseListener(travList);
523 
524 		return catCmb;
525 	}
526 
527 	private Control createWorkAddressWidgets(Composite parent, final Combo addContactCombo, Node entity,
528 			String contactType) {
529 		try {
530 			final Combo catCmb = new Combo(parent, SWT.NONE);
531 			catCmb.setItems(peopleService.getContactService()
532 					.getContactCategories(peopleService.getMainNodeType(entity), contactType, true));
533 			catCmb.select(0);
534 
535 			final Text valueTxt = createRowDataLT(parent, PeopleMsg.linkedCompany.lead(), 200);
536 			CmsUtils.style(valueTxt, ConnectUiStyles.FORCE_BORDER);
537 			valueTxt.setEnabled(false);
538 
539 			final Link chooseOrgLk = new Link(parent, SWT.BOTTOM);
540 
541 			toolkit.adapt(chooseOrgLk, false, false);
542 			chooseOrgLk.setText("<a>" + PeopleMsg.pickup.lead() + "</a>");
543 			final PickUpOrgDialog diag = new PickUpOrgDialog(chooseOrgLk.getShell(),
544 					PeopleMsg.chooseAnOrganisation.lead(), entity.getSession(), systemWorkbenchService, entity);
545 
546 			final Text labelTxt = createRowDataLT(parent, PeopleMsg.aCustomLabel.lead(), 120);
547 
548 			final String PROP_SELECTED_NODE = "selectedNode";
549 
550 			chooseOrgLk.addSelectionListener(new SelectionAdapter() {
551 				private static final long serialVersionUID = -7118320199160680131L;
552 
553 				@Override
554 				public void widgetSelected(final SelectionEvent event) {
555 					diag.open();
556 					Node currNode = diag.getSelected();
557 					valueTxt.setData(PROP_SELECTED_NODE, currNode);
558 					if (currNode != null) {
559 						valueTxt.setText(ConnectJcrUtils.get(currNode, Property.JCR_TITLE));
560 					}
561 				}
562 			});
563 
564 			final Button primaryChk = toolkit.createButton(parent, PeopleMsg.primary.lead(), SWT.CHECK);
565 
566 			final Button validBtn = toolkit.createButton(parent, PeopleMsg.add.lead(), SWT.PUSH);
567 
568 			validBtn.addSelectionListener(new SelectionAdapter() {
569 				private static final long serialVersionUID = 1L;
570 
571 				@Override
572 				public void widgetSelected(SelectionEvent e) {
573 					Node selected = (Node) valueTxt.getData(PROP_SELECTED_NODE);
574 					String label = labelTxt.getText();
575 					String cat = catCmb.getText();
576 					boolean isPrimary = primaryChk.getSelection();
577 					PeopleJcrUtils.createWorkAddress(resourcesService, peopleService, entity, isPrimary, selected, cat,
578 							label);
579 					myFormPart.markDirty();
580 					myFormPart.refresh();
581 				}
582 			});
583 			return catCmb;
584 		} catch (RepositoryException e1) {
585 			throw new PeopleException("Cannot create work address widgets for " + entity, e1);
586 		}
587 	}
588 
589 	private Text createRowDataLT(Composite parent, String msg, int width) {
590 		Text text = toolkit.createText(parent, null, SWT.BORDER);
591 		text.setMessage(msg);
592 		text.setLayoutData(width == 0 ? new RowData() : new RowData(width, SWT.DEFAULT));
593 		return text;
594 	}
595 }