/*
Copyright 2008-2013 Josh Drummond
This file is part of WebPasswordSafe.
WebPasswordSafe 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; either version 2 of the License, or
(at your option) any later version.
WebPasswordSafe 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 WebPasswordSafe; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.webpasswordsafe.client.ui;
import java.util.List;
import net.webpasswordsafe.client.ClientSessionUtil;
import net.webpasswordsafe.client.WebPasswordSafe;
import net.webpasswordsafe.client.i18n.TextMessages;
import net.webpasswordsafe.client.remote.UserService;
import net.webpasswordsafe.common.model.Group;
import net.webpasswordsafe.common.model.User;
import net.webpasswordsafe.common.util.Constants;
import net.webpasswordsafe.common.util.Utils;
import net.webpasswordsafe.common.util.Constants.Function;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.util.Format;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.DualListField;
import com.extjs.gxt.ui.client.widget.form.ListField;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.layout.AbsoluteLayout;
import com.extjs.gxt.ui.client.widget.layout.AbsoluteData;
import com.extjs.gxt.ui.client.widget.form.LabelField;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
/**
* @author Josh Drummond
*
*/
public class GroupDialog extends Window
{
private Group group;
private TextField<String> nameTextBox;
private ListStore<UserData> fromUserStore;
private ListStore<UserData> toUserStore;
private final static TextMessages textMessages = GWT.create(TextMessages.class);
private ClientSessionUtil clientSessionUtil = ClientSessionUtil.getInstance();
public GroupDialog(Group pGroup)
{
this.group = pGroup;
this.setHeading(textMessages.group());
this.setModal(true);
this.setLayout(new AbsoluteLayout());
this.setSize("455", "355");
this.setResizable(false);
LabelField lblfldName = new LabelField(textMessages.name_());
add(lblfldName, new AbsoluteData(6, 13));
lblfldName.setSize("82px", "19px");
nameTextBox = new TextField<String>();
add(nameTextBox, new AbsoluteData(128, 13));
nameTextBox.setSize("306px", "22px");
LabelField lblfldUsers = new LabelField(textMessages.users_());
add(lblfldUsers, new AbsoluteData(6, 49));
lblfldUsers.setSize("54px", "19px");
LabelField lblfldAvailable = new LabelField(textMessages.available());
add(lblfldAvailable, new AbsoluteData(6, 74));
lblfldAvailable.setSize("67px", "19px");
LabelField lblfldMembers = new LabelField(textMessages.members());
add(lblfldMembers, new AbsoluteData(232, 74));
lblfldMembers.setSize("74px", "19px");
DualListField<UserData> membersListBox = new DualListField<UserData>();
add(membersListBox, new AbsoluteData(6, 96));
membersListBox.setSize("428px", "183px");
ListField<UserData> from = membersListBox.getFromList();
ListField<UserData> to = membersListBox.getToList();
from.setSize(300, 100);
from.setDisplayField(Constants.FULLNAME);
fromUserStore = new ListStore<UserData>();
fromUserStore.sort(Constants.FULLNAME, SortDir.ASC);
from.setStore(fromUserStore);
to.setDisplayField(Constants.FULLNAME);
to.setSize(300, 100);
toUserStore = new ListStore<UserData>();
toUserStore.sort(Constants.FULLNAME, SortDir.ASC);
to.setStore(toUserStore);
Button saveButton = new Button(textMessages.save(),
new SelectionListener<ButtonEvent>()
{
@Override
public void componentSelected(ButtonEvent ce)
{
doSave();
}
});
Button deleteButton = new Button(textMessages.delete(),
new SelectionListener<ButtonEvent>()
{
@Override
public void componentSelected(ButtonEvent ce)
{
doVerifyDelete();
}
});
Button cancelButton = new Button(textMessages.cancel(),
new SelectionListener<ButtonEvent>()
{
@Override
public void componentSelected(ButtonEvent ce)
{
doCancel();
}
});
setButtonAlign(HorizontalAlignment.CENTER);
addButton(saveButton);
if ((group.getId() != 0) && clientSessionUtil.isAuthorized(Function.DELETE_GROUP))
{
addButton(deleteButton);
}
addButton(cancelButton);
setFields();
}
@Override
public void show()
{
super.show();
setFocusWidget(nameTextBox);
}
private void doVerifyDelete()
{
MessageBox.confirm(textMessages.confirmDelete(), textMessages.groupConfirmDelete(), new Listener<MessageBoxEvent>()
{
@Override
public void handleEvent(MessageBoxEvent be)
{
if (be.getButtonClicked().getItemId().equals(Dialog.YES))
{
doDelete();
}
}
});
}
private void doDelete()
{
AsyncCallback<Void> callback = new AsyncCallback<Void>()
{
@Override
public void onFailure(Throwable caught)
{
WebPasswordSafe.handleServerFailure(caught);
}
@Override
public void onSuccess(Void result)
{
Info.display(textMessages.status(), textMessages.groupDeleted());
hide();
}
};
UserService.Util.getInstance().deleteGroup(group, callback);
}
private void doSave()
{
if (validateFields())
{
group.setName(Utils.safeString(nameTextBox.getValue()));
group.removeUsers();
for (UserData userData : toUserStore.getModels())
{
group.addUser((User)userData.get(Constants.USER));
}
final AsyncCallback<Boolean> callbackCheck = new AsyncCallback<Boolean>()
{
@Override
public void onFailure(Throwable caught)
{
WebPasswordSafe.handleServerFailure(caught);
}
@Override
public void onSuccess(Boolean result)
{
// true => group name already taken, else go ahead and save
if (result)
{
MessageBox.alert(textMessages.error(), textMessages.groupNameAlreadyExists(), null);
}
else
{
AsyncCallback<Void> callback = new AsyncCallback<Void>()
{
@Override
public void onFailure(Throwable caught)
{
WebPasswordSafe.handleServerFailure(caught);
}
@Override
public void onSuccess(Void result)
{
Info.display(textMessages.status(), textMessages.groupSaved());
hide();
}
};
if (group.getId() == 0)
{
UserService.Util.getInstance().addGroup(group, callback);
}
else
{
UserService.Util.getInstance().updateGroup(group, callback);
}
}
}
};
UserService.Util.getInstance().isGroupTaken(group.getName(), group.getId(), callbackCheck);
}
}
private boolean validateFields()
{
if (Utils.safeString(nameTextBox.getValue()).equals(""))
{
MessageBox.alert(textMessages.error(), textMessages.mustEnterName(), null);
return false;
}
if (Utils.safeString(nameTextBox.getValue()).length() > Group.LENGTH_NAME)
{
MessageBox.alert(textMessages.error(), textMessages.tooLongName(), null);
return false;
}
return true;
}
private void setFields()
{
nameTextBox.setValue(group.getName());
for (User user : group.getUsers())
{
toUserStore.add(new UserData(user));
}
loadAvailableUsers();
}
private void loadAvailableUsers()
{
AsyncCallback<List<User>> callback = new AsyncCallback<List<User>>()
{
@Override
public void onFailure(Throwable caught)
{
WebPasswordSafe.handleServerFailure(caught);
}
@Override
public void onSuccess(List<User> result)
{
refreshAvailableUsers(result);
}
};
UserService.Util.getInstance().getUsers(false, callback);
}
private void refreshAvailableUsers(List<User> users)
{
for (User user : users)
{
if (!group.getUsers().contains(user))
{
fromUserStore.add(new UserData(user));
}
}
}
private void doCancel()
{
hide();
}
private class UserData extends BaseModel
{
private static final long serialVersionUID = 1L;
public UserData(User user)
{
set(Constants.ID, user.getId());
set(Constants.FULLNAME, Format.htmlEncode(user.getFullname()));
set(Constants.USER, user);
}
@Override
public String toString()
{
return get(Constants.FULLNAME);
}
}
}