/////////////////////////////////////////////////////////////////////////////
//
// 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.plugins.todo;
import java.util.Date;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.visit.IVisit;
import org.apache.wicket.util.visit.IVisitor;
import org.hibernate.Hibernate;
import org.projectforge.core.ConfigXml;
import org.projectforge.core.Priority;
import org.projectforge.task.TaskDO;
import org.projectforge.user.GroupDO;
import org.projectforge.user.PFUserDO;
import org.projectforge.user.UserGroupCache;
import org.projectforge.user.UserPrefDO;
import org.projectforge.user.UserPrefDao;
import org.projectforge.web.dialog.ModalDialog;
import org.projectforge.web.task.TaskSelectPanel;
import org.projectforge.web.user.NewGroupSelectPanel;
import org.projectforge.web.user.UserSelectPanel;
import org.projectforge.web.wicket.AbstractEditForm;
import org.projectforge.web.wicket.WicketUtils;
import org.projectforge.web.wicket.bootstrap.GridSize;
import org.projectforge.web.wicket.components.DatePanel;
import org.projectforge.web.wicket.components.DatePanelSettings;
import org.projectforge.web.wicket.components.LabelValueChoiceRenderer;
import org.projectforge.web.wicket.components.MaxLengthTextArea;
import org.projectforge.web.wicket.components.RequiredMaxLengthTextField;
import org.projectforge.web.wicket.components.SingleButtonPanel;
import org.projectforge.web.wicket.flowlayout.ButtonPanel;
import org.projectforge.web.wicket.flowlayout.CheckBoxButton;
import org.projectforge.web.wicket.flowlayout.DivPanel;
import org.projectforge.web.wicket.flowlayout.FieldsetPanel;
import org.projectforge.web.wicket.flowlayout.TextAreaPanel;
public class ToDoEditForm extends AbstractEditForm<ToDoDO, ToDoEditPage>
{
private static final long serialVersionUID = -6208809585214296635L;
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(ToDoEditForm.class);
@SpringBean(name = "userGroupCache")
private UserGroupCache userGroupCache;
@SpringBean(name = "userPrefDao")
private UserPrefDao userPrefDao;
protected boolean saveAsTemplate, sendNotification = true, sendShortMessage;
@SuppressWarnings("unused")
private String templateName; // Used by Wicket
private ModalDialog closeToDoDialog;
private MaxLengthTextArea commentTextArea, closeToDoDialogCommentTextArea;
protected NewGroupSelectPanel groupSelectPanel;
public ToDoEditForm(final ToDoEditPage parentPage, final ToDoDO data)
{
super(parentPage, data);
}
@SuppressWarnings("serial")
@Override
protected void init()
{
super.init();
gridBuilder.newGridPanel();
if (isNew() == true) {
// Favorites
final String[] templateNames = userPrefDao.getPrefNames(ToDoPlugin.USER_PREF_AREA);
if (templateNames != null && templateNames.length > 0) {
// DropDownChoice templates
final FieldsetPanel fs = gridBuilder.newFieldset(getString("templates"));
final LabelValueChoiceRenderer<String> templateNamesChoiceRenderer = new LabelValueChoiceRenderer<String>();
templateNamesChoiceRenderer.addValue("", getString("userPref.template.select"));
for (final String name : templateNames) {
templateNamesChoiceRenderer.addValue(name, name);
}
final DropDownChoice<String> templateNamesChoice = new DropDownChoice<String>(fs.getDropDownChoiceId(), new PropertyModel<String>(
this, "templateName"), templateNamesChoiceRenderer.getValues(), templateNamesChoiceRenderer) {
@Override
protected boolean wantOnSelectionChangedNotifications()
{
return true;
}
@Override
protected CharSequence getDefaultChoice(final String selected)
{
return "";
}
@SuppressWarnings({ "unchecked", "rawtypes"})
@Override
protected void onSelectionChanged(final String newSelection)
{
if (StringUtils.isNotEmpty(newSelection) == true) {
// Fill fields with selected template values:
final UserPrefDO userPref = userPrefDao.getUserPref(ToDoPlugin.USER_PREF_AREA, newSelection);
if (userPref != null) {
userPrefDao.fillFromUserPrefParameters(userPref, data);
}
templateName = "";
// Mark all form components as model changed.
visitFormComponents(new IVisitor() {
@Override
public void component(final Object object, final IVisit visit)
{
final FormComponent< ? > fc = (FormComponent< ? >) object;
fc.modelChanged();
visit.dontGoDeeper();
}
});
}
}
};
templateNamesChoice.setNullValid(true);
fs.add(templateNamesChoice);
}
}
{
// Subject
final FieldsetPanel fs = gridBuilder.newFieldset(ToDoDO.class, "subject");
final RequiredMaxLengthTextField subject = new RequiredMaxLengthTextField(fs.getTextFieldId(), new PropertyModel<String>(data,
"subject"));
if (isNew() == true) {
// Only focus for new to-do's:
subject.add(WicketUtils.setFocus());
}
fs.add(subject);
}
gridBuilder.newSplitPanel(GridSize.COL50);
{
// ToDo type
final FieldsetPanel fs = gridBuilder.newFieldset(ToDoDO.class, "type");
final LabelValueChoiceRenderer<ToDoType> typeChoiceRenderer = new LabelValueChoiceRenderer<ToDoType>(this, ToDoType.values());
fs.addDropDownChoice(new PropertyModel<ToDoType>(data, "type"), typeChoiceRenderer.getValues(), typeChoiceRenderer)
.setNullValid(true);
}
{
// Status
final FieldsetPanel fs = gridBuilder.newFieldset(ToDoDO.class, "status");
final LabelValueChoiceRenderer<ToDoStatus> statusChoiceRenderer = new LabelValueChoiceRenderer<ToDoStatus>(this, ToDoStatus.values());
fs.addDropDownChoice(new PropertyModel<ToDoStatus>(data, "status"), statusChoiceRenderer.getValues(), statusChoiceRenderer)
.setNullValid(true);
}
{
// Due date
final FieldsetPanel fs = gridBuilder.newFieldset(ToDoDO.class, "dueDate");
fs.add(new DatePanel(fs.newChildId(), new PropertyModel<Date>(data, "dueDate"), DatePanelSettings.get().withTargetType(
java.sql.Date.class)));
}
gridBuilder.newSplitPanel(GridSize.COL50);
{
// Priority
final FieldsetPanel fs = gridBuilder.newFieldset(ToDoDO.class, "priority");
final LabelValueChoiceRenderer<Priority> priorityChoiceRenderer = new LabelValueChoiceRenderer<Priority>(this, Priority.values());
fs.addDropDownChoice(new PropertyModel<Priority>(data, "priority"), priorityChoiceRenderer.getValues(), priorityChoiceRenderer)
.setNullValid(true);
}
{
// Assignee
final FieldsetPanel fs = gridBuilder.newFieldset(ToDoDO.class, "assignee");
PFUserDO assignee = data.getAssignee();
if (Hibernate.isInitialized(assignee) == false) {
assignee = userGroupCache.getUser(assignee.getId());
data.setAssignee(assignee);
}
final UserSelectPanel assigneeUserSelectPanel = new UserSelectPanel(fs.newChildId(), new PropertyModel<PFUserDO>(data, "assignee"),
parentPage, "assigneeId");
fs.add(assigneeUserSelectPanel);
assigneeUserSelectPanel.setRequired(true);
assigneeUserSelectPanel.init();
}
{
// Reporter
final FieldsetPanel fs = gridBuilder.newFieldset(ToDoDO.class, "reporter");
PFUserDO reporter = data.getReporter();
if (Hibernate.isInitialized(reporter) == false) {
reporter = userGroupCache.getUser(reporter.getId());
data.setReporter(reporter);
}
final UserSelectPanel reporterUserSelectPanel = new UserSelectPanel(fs.newChildId(), new PropertyModel<PFUserDO>(data, "reporter"),
parentPage, "reporterId");
fs.add(reporterUserSelectPanel);
reporterUserSelectPanel.init();
}
gridBuilder.newGridPanel();
{
// Task
final FieldsetPanel fs = gridBuilder.newFieldset(ToDoDO.class, "task");
final TaskSelectPanel taskSelectPanel = new TaskSelectPanel(fs, new PropertyModel<TaskDO>(data, "task"), parentPage, "taskId");
fs.add(taskSelectPanel);
taskSelectPanel.init();
fs.addHelpIcon(new ResourceModel("plugins.todo.task.tooltip.title"), new ResourceModel("plugins.todo.task.tooltip.content"));
}
{
// Group
final FieldsetPanel fs = gridBuilder.newFieldset(ToDoDO.class, "group");
groupSelectPanel = new NewGroupSelectPanel(fs.newChildId(), new PropertyModel<GroupDO>(data, "group"),
parentPage, "groupId");
fs.add(groupSelectPanel);
fs.setLabelFor(groupSelectPanel);
fs.addHelpIcon(new ResourceModel("plugins.todo.group.tooltip.title"), new ResourceModel("plugins.todo.group.tooltip.content"));
groupSelectPanel.init();
}
{
// Description
final FieldsetPanel fs = gridBuilder.newFieldset(ToDoDO.class, "description");
fs.add(new MaxLengthTextArea(fs.getTextAreaId(), new PropertyModel<String>(data, "description"))).setAutogrow();
}
{
// Comment
final FieldsetPanel fs = gridBuilder.newFieldset(ToDoDO.class, "comment");
commentTextArea = new MaxLengthTextArea(fs.getTextAreaId(), new PropertyModel<String>(data, "comment"));
fs.add(commentTextArea).setAutogrow();
}
{
// Options
final FieldsetPanel fs = gridBuilder.newFieldset(getString("label.options")).suppressLabelForWarning();
final DivPanel checkBoxButton = fs.addNewCheckBoxButtonDiv();
if (ConfigXml.getInstance().isSendMailConfigured() == true) {
checkBoxButton.add(new CheckBoxButton(checkBoxButton.newChildId(), new PropertyModel<Boolean>(this, "sendNotification"),
getString("label.sendEMailNotification")).setTooltip(getString("plugins.todo.notification.tooltip")));
}
// if (ConfigXml.getInstance().isSmsConfigured() == true) {
// checkBoxPanel.add(new CheckBoxPanel(checkBoxPanel.newChildId(), new PropertyModel<Boolean>(this, "sendShortMessage"),
// getString("label.sendShortMessage")));
// }
checkBoxButton.add(new CheckBoxButton(checkBoxButton.newChildId(), new PropertyModel<Boolean>(this, "saveAsTemplate"),
getString("userPref.saveAsTemplate")));
}
if (isNew() == false
&& getData().getStatus() != ToDoStatus.CLOSED
&& getData().isDeleted() == false
&& getBaseDao().hasLoggedInUserUpdateAccess(getData(), getData(), false)) {
// Close button:
final AjaxButton closeButton = new AjaxButton(ButtonPanel.BUTTON_ID, this) {
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form< ? > form)
{
// repaint the feedback panel so that it is hidden:
target.add(((ToDoEditForm) form).getFeedbackPanel());
getData().setComment(commentTextArea.getConvertedInput());
closeToDoDialogCommentTextArea.modelChanged();
target.add(closeToDoDialogCommentTextArea);
closeToDoDialog.open(target);
// Focus doesn't yet work:
// + "$('#"
// + closeToDoDialog.getMainContainerMarkupId()
// + "').on('shown', function () { $('"
// + closeToDialogCommentTextArea.getMarkupId()
// + "').focus(); })");
}
@Override
protected void onError(final AjaxRequestTarget target, final Form< ? > form)
{
target.add(((ToDoEditForm) form).getFeedbackPanel());
}
};
final SingleButtonPanel closeButtonPanel = new SingleButtonPanel(actionButtons.newChildId(), closeButton,
getString("plugins.todo.button.close"));
actionButtons.add(2, closeButtonPanel);
addCloseToDoDialog();
}
}
@SuppressWarnings("serial")
private void addCloseToDoDialog()
{
closeToDoDialog = new ModalDialog(parentPage.newModalDialogId()) {
@Override
public void init()
{
setTitle(getString("plugins.todo.closeDialog.heading"));
init(new Form<String>(getFormId()));
{
final FieldsetPanel fs = gridBuilder.newFieldset(ToDoDO.class, "comment");
closeToDoDialogCommentTextArea = new MaxLengthTextArea(TextAreaPanel.WICKET_ID, new PropertyModel<String>(data, "comment"),
commentTextArea.getMaxLength());
closeToDoDialogCommentTextArea.setOutputMarkupId(true).add(AttributeModifier.replace("tabindex", "-1"));
fs.add(new TextAreaPanel(fs.newChildId(), closeToDoDialogCommentTextArea));
WicketUtils.setHeight(closeToDoDialogCommentTextArea, 20);
}
}
/**
* @see org.projectforge.web.dialog.ModalDialog#onCloseButtonSubmit(org.apache.wicket.ajax.AjaxRequestTarget)
*/
@Override
protected boolean onCloseButtonSubmit(final AjaxRequestTarget target)
{
getData().setStatus(ToDoStatus.CLOSED);
parentPage.updateAndClose();
return true;
};
};
parentPage.add(closeToDoDialog);
closeToDoDialog.setCloseButtonLabel(getString("plugins.todo.button.close")).init();
}
@Override
protected Logger getLogger()
{
return log;
}
}