///////////////////////////////////////////////////////////////////////////// // // Project ProjectForge Community Edition // www.projectforge.org // // Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de) // // ProjectForge is dual-licensed. // // This community edition is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as published // by the Free Software Foundation; version 3 of the License. // // This community edition is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General // Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, see http://www.gnu.org/licenses/. // ///////////////////////////////////////////////////////////////////////////// package org.projectforge.web.address; import java.io.Serializable; import java.util.Date; import java.util.List; import java.util.Locale; import org.apache.commons.lang.StringUtils; import org.apache.wicket.Component; import org.apache.wicket.markup.html.form.Button; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.SubmitLink; import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.spring.injection.annot.SpringBean; import org.apache.wicket.util.convert.IConverter; import org.projectforge.address.AddressDO; import org.projectforge.address.AddressDao; import org.projectforge.address.AddressFilter; import org.projectforge.address.PhoneType; import org.projectforge.common.BeanHelper; import org.projectforge.common.NumberHelper; import org.projectforge.common.RecentQueue; import org.projectforge.common.StringHelper; import org.projectforge.core.ConfigXml; import org.projectforge.user.PFUserContext; import org.projectforge.user.UserDao; import org.projectforge.web.HtmlHelper; import org.projectforge.web.wicket.AbstractEditPage; import org.projectforge.web.wicket.AbstractStandardForm; import org.projectforge.web.wicket.autocompletion.PFAutoCompleteTextField; import org.projectforge.web.wicket.bootstrap.GridSize; import org.projectforge.web.wicket.components.LabelValueChoiceRenderer; import org.projectforge.web.wicket.components.SingleButtonPanel; import org.projectforge.web.wicket.flowlayout.DivPanel; import org.projectforge.web.wicket.flowlayout.FieldsetPanel; import org.projectforge.web.wicket.flowlayout.InputPanel; import org.projectforge.web.wicket.flowlayout.TextLinkPanel; import org.projectforge.web.wicket.flowlayout.TextPanel; public class PhoneCallForm extends AbstractStandardForm<Object, PhoneCallPage> { private static final long serialVersionUID = -2138017238114715368L; private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(PhoneCallForm.class); private static final String USER_PREF_KEY_RECENTS = "phoneCalls"; @SpringBean(name = "addressDao") private AddressDao addressDao; @SpringBean(name = "userDao") private UserDao userDao; protected AddressDO address; protected PFAutoCompleteTextField<AddressDO> numberTextField; private DivPanel addressPanel; protected String phoneNumber; private String myCurrentPhoneId; Date lastSuccessfulPhoneCall; private RecentQueue<String> recentSearchTermsQueue; public PhoneCallForm(final PhoneCallPage parentPage) { super(parentPage); } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(final String phoneNumber) { this.phoneNumber = phoneNumber; } public String getMyCurrentPhoneId() { if (myCurrentPhoneId == null) { myCurrentPhoneId = parentPage.getRecentMyPhoneId(); } return myCurrentPhoneId; } public void setMyCurrentPhoneId(final String myCurrentPhoneId) { this.myCurrentPhoneId = myCurrentPhoneId; if (this.myCurrentPhoneId != null) { parentPage.setRecentMyPhoneId(this.myCurrentPhoneId); } } public AddressDO getAddress() { return address; } public void setAddress(final AddressDO address) { this.address = address; } /** * @see org.projectforge.web.wicket.AbstractStandardForm#createMessageComponent() */ @SuppressWarnings("serial") @Override protected Component createMessageComponent() { final DivPanel messagePanel = new DivPanel("message") { /** * @see org.apache.wicket.Component#isVisible() */ @Override public boolean isVisible() { return StringUtils.isNotBlank(parentPage.result); } @Override public void onAfterRender() { super.onAfterRender(); parentPage.result = null; } }; messagePanel.add(new TextPanel(messagePanel.newChildId(), new Model<String>() { @Override public String getObject() { return parentPage.result; } })); return messagePanel; } @Override @SuppressWarnings({ "serial", "unchecked", "rawtypes"}) protected void init() { super.init(); gridBuilder.newSplitPanel(GridSize.COL50); FieldsetPanel fs = gridBuilder.newFieldset(getString("address.phoneCall.number.label"), getString("address.phoneCall.number.labeldescription")); numberTextField = new PFAutoCompleteTextField<AddressDO>(InputPanel.WICKET_ID, new Model() { @Override public Serializable getObject() { // Pseudo object for storing search string (title field is used for this foreign purpose). return new AddressDO().setName(phoneNumber); } @Override public void setObject(final Serializable object) { if (object != null) { if (object instanceof String) { phoneNumber = (String) object; } } else { phoneNumber = ""; } } }) { @Override protected List<AddressDO> getChoices(final String input) { final AddressFilter addressFilter = new AddressFilter(); addressFilter.setSearchString(input); addressFilter.setSearchFields("name", "firstName", "organization"); return addressDao.getList(addressFilter); } @Override protected List<String> getRecentUserInputs() { return getRecentSearchTermsQueue().getRecents(); } @Override protected String formatLabel(final AddressDO address) { return StringHelper.listToString(", ", address.getName(), address.getFirstName(), address.getOrganization()); } @Override protected String formatValue(final AddressDO address) { return "id:" + address.getId(); } /** * @see org.apache.wicket.Component#getConverter(java.lang.Class) */ @Override public <C> IConverter<C> getConverter(final Class<C> type) { return new IConverter() { @Override public Object convertToObject(final String value, final Locale locale) { phoneNumber = value; return new AddressDO().setName(phoneNumber); } @Override public String convertToString(final Object value, final Locale locale) { return phoneNumber; } }; } }; numberTextField.withLabelValue(true).withMatchContains(true).withMinChars(2).withFocus(true).withAutoSubmit(true); if (StringUtils.isBlank(phoneNumber) == true) { if (address != null) { final String no = parentPage.getFirstPhoneNumber(); if (StringUtils.isNotBlank(no) == true) { phoneNumber = parentPage.extractPhonenumber(no); } } else { final String recentNumber = getRecentSearchTermsQueue().get(0); if (StringUtils.isNotBlank(recentNumber) == true) { phoneNumber = recentNumber; } } } fs.add(numberTextField); fs.addKeyboardHelpIcon(new ResourceModel("tooltip.autocompletion.title"), new ResourceModel("address.directCall.number.tooltip")); { // DropDownChoice myCurrentPhoneId fs = gridBuilder.newFieldset(getString("address.myCurrentPhoneId")); final LabelValueChoiceRenderer<String> myCurrentPhoneIdChoiceRenderer = new LabelValueChoiceRenderer<String>(); final String[] ids = userDao.getPersonalPhoneIdentifiers(PFUserContext.getUser()); if (ids == null) { myCurrentPhoneIdChoiceRenderer.addValue("--", getString("user.personalPhoneIdentifiers.pleaseDefine")); } else { for (final String id : ids) { myCurrentPhoneIdChoiceRenderer.addValue(id, id); } } final DropDownChoice myCurrentPhoneIdChoice = new DropDownChoice(fs.getDropDownChoiceId(), new PropertyModel(this, "myCurrentPhoneId"), myCurrentPhoneIdChoiceRenderer.getValues(), myCurrentPhoneIdChoiceRenderer); myCurrentPhoneIdChoice.setNullValid(false).setRequired(true); fs.add(myCurrentPhoneIdChoice); fs.addHelpIcon(new ResourceModel("address.myCurrentPhoneId.tooltip.title"), new ResourceModel("address.myCurrentPhoneId.tooltip.content")); } addressPanel = gridBuilder.newSplitPanel(GridSize.COL50).getPanel(); { final Link<String> addressViewLink = new Link<String>(TextLinkPanel.LINK_ID) { @Override public void onClick() { if (address == null) { log.error("Oups should not occur: AddressViewLink is shown without a given address. Ignoring link."); return; } final PageParameters params = new PageParameters(); params.add(AbstractEditPage.PARAMETER_KEY_ID, address.getId()); setResponsePage(new AddressViewPage(params, parentPage)); } }; final TextLinkPanel addressLinkPanel = new TextLinkPanel(addressPanel.newChildId(), addressViewLink, new Model<String>() { @Override public String getObject() { if (address == null) { return ""; } final StringBuffer buf = new StringBuffer(); if (address.getForm() != null) { buf.append(getString(address.getForm().getI18nKey())).append(" "); } if (StringUtils.isNotBlank(address.getTitle()) == true) { buf.append(address.getTitle()).append(" "); } if (StringUtils.isNotBlank(address.getFirstName()) == true) { buf.append(address.getFirstName()).append(" "); } if (StringUtils.isNotBlank(address.getName()) == true) { buf.append(address.getName()); } return buf.toString(); } }); addressPanel.add(addressLinkPanel); addLineBreak(); } { addPhoneNumber("businessPhone", getString(PhoneType.BUSINESS.getI18nKey())); addPhoneNumber("mobilePhone", getString(PhoneType.MOBILE.getI18nKey())); addPhoneNumber("privatePhone", getString(PhoneType.PRIVATE.getI18nKey())); addPhoneNumber("privateMobilePhone", getString(PhoneType.PRIVATE_MOBILE.getI18nKey())); } { final Button callButton = new Button(SingleButtonPanel.WICKET_ID, new Model<String>("call")) { @Override public final void onSubmit() { parentPage.call(); } }; final SingleButtonPanel callButtonPanel = new SingleButtonPanel(actionButtons.newChildId(), callButton, getString("address.directCall.call"), SingleButtonPanel.DEFAULT_SUBMIT); actionButtons.add(callButtonPanel); setDefaultButton(callButton); } final String url = ConfigXml.getInstance().getTelephoneSystemOperatorPanelUrl(); if (url != null) { final DivPanel section = gridBuilder.newGridPanel().getPanel(); final TextPanel showOperatorPanel = new TextPanel(section.newChildId(), url); showOperatorPanel.getLabel().setEscapeModelStrings(false); section.add(showOperatorPanel); } } private void addLineBreak() { final TextPanel lineBreak = new TextPanel(addressPanel.newChildId(), "<br/>"); lineBreak.getLabel().setEscapeModelStrings(false); addressPanel.add(lineBreak); } @SuppressWarnings("serial") private void addPhoneNumber(final String property, final String label) { final SubmitLink numberLink = new SubmitLink(TextLinkPanel.LINK_ID) { @Override public void onSubmit() { final String number = (String) BeanHelper.getProperty(address, property); setPhoneNumber(parentPage.extractPhonenumber(number)); numberTextField.setModelObject(new AddressDO().setName(getPhoneNumber())); numberTextField.modelChanged(); parentPage.call(); } }; final TextLinkPanel numberLinkPanel = new TextLinkPanel(addressPanel.newChildId(), numberLink, new Model<String>() { @Override public String getObject() { final String number = (String) BeanHelper.getProperty(address, property); return HtmlHelper.escapeHtml(number + " (" + label + ")\n", true); } }) { /** * @see org.apache.wicket.Component#isVisible() */ @Override public boolean isVisible() { if (address == null) { return false; } final String number = (String) BeanHelper.getProperty(address, property); return (StringUtils.isNotBlank(number) == true); } }; numberLinkPanel.getLabel().setEscapeModelStrings(false); addressPanel.add(numberLinkPanel); } protected String getPhoneNumberAndPerson(final AddressDO address, final PhoneType phoneType, final String number, final String countryPrefix) { return StringHelper.listToString(", ", NumberHelper.extractPhonenumber(number, countryPrefix) + ": " + address.getName(), address.getFirstName(), getString(phoneType.getI18nKey()), address.getOrganization()); } @SuppressWarnings("unchecked") protected RecentQueue<String> getRecentSearchTermsQueue() { if (recentSearchTermsQueue == null) { recentSearchTermsQueue = (RecentQueue<String>) parentPage.getUserPrefEntry(USER_PREF_KEY_RECENTS); } if (recentSearchTermsQueue == null) { recentSearchTermsQueue = (RecentQueue<String>) parentPage .getUserPrefEntry("org.projectforge.web.address.PhoneCallAction:recentSearchTerms"); if (recentSearchTermsQueue != null) { // Old entries: parentPage.putUserPrefEntry(USER_PREF_KEY_RECENTS, recentSearchTermsQueue, true); parentPage.removeUserPrefEntry("org.projectforge.web.address.PhoneCallAction:recentSearchTerms"); } } if (recentSearchTermsQueue == null) { recentSearchTermsQueue = new RecentQueue<String>(); parentPage.putUserPrefEntry(USER_PREF_KEY_RECENTS, recentSearchTermsQueue, true); } return recentSearchTermsQueue; } }