package com.simonepezzano.hshare.dialogs;
import hshare.Activator;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import com.simonepezzano.hshare.HLog;
import com.simonepezzano.hshare.HUsers;
import com.simonepezzano.hshare.Statics;
import com.simonepezzano.hshare.views.LogsView;
/**
* The users editing dialog
* @author Simone Pezzano
*
*/
public class UsersDialog implements SelectionListener,IDoubleClickListener,ISelectionChangedListener{
private Shell window;
private TableViewer list;
private Button btnClose, btnAdd, btnEdit, btnDel;
private HUsers users;
private Provider provider;
private LabelProvider labProvider;
public static final int WIDTH=400;
public static final int HEIGHT=300;
/**
* Default constructor
* @param parent the parent Shell
*/
public UsersDialog(Shell parent) {
window = new Shell(parent);
window.setText("Users");
window.setSize(WIDTH, HEIGHT);
window.setLocation(Statics.getOriginForCenter(WIDTH, HEIGHT));
window.setLayout(new GridLayout());
// Add a row of User Management actions just above the list
Composite userMmgt = new Composite(window, SWT.NONE);
userMmgt.setLayout(new RowLayout());
userMmgt.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
btnAdd = new Button(userMmgt,SWT.PUSH);
btnAdd.setText("Add user");
btnAdd.addSelectionListener(this);
btnEdit = new Button(userMmgt,SWT.PUSH);
btnEdit.setText("Edit user");
btnEdit.addSelectionListener(this);
btnDel = new Button(userMmgt,SWT.PUSH);
btnDel.setText("Remove user");
btnDel.addSelectionListener(this);
// Edit and delete buttons are disabled by default
btnEdit.setEnabled(false);
btnDel.setEnabled(false);
// List of users
list = new TableViewer(window,SWT.BORDER|SWT.FULL_SELECTION);
list.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
// Close button
Composite btnCmp = new Composite(window,SWT.NONE);
btnCmp.setLayout(new RowLayout());
btnCmp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
btnClose = new Button(btnCmp,SWT.PUSH);
btnClose.setText("Close");
btnClose.addSelectionListener(this);
try {
users = new HUsers();
} catch (URISyntaxException e) {
HLog.iologger.error("Could not determine users file. Are you sure you're doing this right?",e);
} catch (IOException e) {
HLog.iologger.error("Could not create users file... something wrong with the FS?",e);
LogsView.instance.addItem("I cannot create a users file. Maybe a problem with file permissions?");
} catch (DocumentException e) {
HLog.doclogger.error("The document we loaded/created for users seems to be corrupted... check syntax",e);
}
provider = new Provider(users.getDocument().getRootElement());
labProvider = new LabelProvider();
list.setContentProvider(provider);
list.setLabelProvider(labProvider);
list.setInput(new Element[]{});
list.addDoubleClickListener(this);
list.addSelectionChangedListener(this);
}
/**
* Opens the window
*/
public void open(){
window.open();
}
public void widgetDefaultSelected(SelectionEvent e) {}
public void widgetSelected(SelectionEvent e) {
if(e.getSource().equals(btnAdd)){
addItemAction();
}
if(e.getSource().equals(btnEdit)){
editItemAction();
}
if(e.getSource().equals(btnDel)){
removeItemAction();
}
if(e.getSource().equals(btnClose)){
closeWindowAction();
}
}
/**
* Opens the user editor dialog for adding a new user
*/
private void addItemAction(){
UserEditor ed = new UserEditor(window,null,users.getDocument().getRootElement());
ed.open();
handleUserEditorResult(ed);
}
/**
* Opens the user editor dialog for editing an existing user
*/
private void editItemAction(){
IStructuredSelection sel = (IStructuredSelection) list.getSelection();
Element selElement = (Element) sel.getFirstElement();
if(selElement==null)
return;
UserEditor ed = new UserEditor(window,selElement,users.getDocument().getRootElement());
ed.open();
handleUserEditorResult(ed);
}
/**
* Removes the selected user
*/
private void removeItemAction(){
IStructuredSelection sel = (IStructuredSelection) list.getSelection();
if(sel==null)
return;
Element selElement = (Element) sel.getFirstElement();
if(selElement==null)
return;
selElement.detach();
try {
users.save();
} catch (IOException e1) {
HLog.iologger.error("Cannot save users file!",e1);
LogsView.instance.addItem("Could not save users file. Check FS");
}
list.refresh();
}
/**
* Closes ths window
*/
private void closeWindowAction(){
window.dispose();
}
/**
* Handles the 'modal' aspect of the user editor window and handles
* the result
* @param ed a user editor object
*/
private void handleUserEditorResult(UserEditor ed){
while(!ed.isDisposed())
if(!window.getDisplay().readAndDispatch())
window.getDisplay().sleep();
if(ed.getResult())
try {
users.save();
list.refresh();
} catch (IOException e1) {
HLog.iologger.error("Cannot save users file!",e1);
LogsView.instance.addItem("Could not save users file. Check FS");
}
}
public void doubleClick(DoubleClickEvent event) {
editItemAction();
}
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection sel = (IStructuredSelection) event.getSelection();
if(sel!=null){
boolean enabled = sel.getFirstElement()!=null;
btnEdit.setEnabled(enabled);
btnDel.setEnabled(enabled);
return;
}
}
}
/**
* The only content provider for UsersDialog
* @author Simone Pezzano
*
*/
class Provider implements IStructuredContentProvider{
private Element users;
public Provider(Element users){
this.users = users;
}
@SuppressWarnings("unchecked")
public Object[] getElements(Object inputElement) {
Element[] els = new Element[0];
if(users==null || users.elements().size()==0)
return els;
List<Element> elements = users.elements();
els = elements.toArray(els);
return els;
}
public void dispose() {}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
}
/**
* The only label provider for usersdialog
* @author Simone Pezzano
*
*/
class LabelProvider implements ILabelProvider{
public Image getImage(Object element) {
return Activator.getImageDescriptor("icons/check-user.png").createImage();
}
public String getText(Object element) {
return ((Element)element).attributeValue("username");
}
public void addListener(ILabelProviderListener listener) {}
public void dispose() {}
public boolean isLabelProperty(Object element, String property) {
return false;
}
public void removeListener(ILabelProviderListener listener) {}
}
/**
* The mini-dialog for editing users details
* @author Simone Pezzano
*
*/
class UserEditor implements SelectionListener{
private Shell window;
private Text uname,password;
private Button save,cancel;
private Element element;
private Element rootElement;
private boolean result = false;
public static final int WIDTH=300;
public static final int HEIGHT=200;
/**
* Default constructor
* @param parent the parent Shell
* @param el the user descriptor to be edited
* @param root the parent element
*/
public UserEditor(Shell parent,Element el,Element root){
element = el;
rootElement = root;
window = new Shell(parent);
window.setText("Editing user");
window.setLocation(parent.getLocation().x+20, parent.getLocation().y+20);
window.setSize(WIDTH, HEIGHT);
window.setLayout(new GridLayout());
new Label(window,SWT.NONE).setText("Username:");
uname = new Text(window,SWT.BORDER);
uname.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
new Label(window,SWT.NONE).setText("Password:");
password = new Text(window,SWT.BORDER|SWT.PASSWORD);
password.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Composite cmp = new Composite(window,SWT.NONE);
cmp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
cmp.setLayout(new RowLayout());
save = new Button(cmp,SWT.PUSH);
save.setText("Save");
cancel = new Button(cmp,SWT.PUSH);
cancel.setText("Cancel");
save.addSelectionListener(this);
cancel.addSelectionListener(this);
uname.setEnabled(true);
save.setEnabled(false);
if(element!=null){
save.setEnabled(true);
uname.setEnabled(false);
uname.setText(el.attributeValue("username"));
password.setText(el.attributeValue("password"));
}
uname.addModifyListener(new ModifyListener(){
public void modifyText(ModifyEvent e) {
if(uname.getText().length()>0)
save.setEnabled(true);
else
save.setEnabled(false);
}
});
}
/**
* @return true if user pressed save button
*/
public boolean getResult(){
return result;
}
/**
* Opens the window
*/
public void open(){
window.open();
}
/**
* @return true if the window has been disposed
*/
public boolean isDisposed(){
return window.isDisposed();
}
public void widgetDefaultSelected(SelectionEvent e) {}
public void widgetSelected(SelectionEvent e) {
if(e.getSource().equals(save)){
if(element!=null)
element.attribute("password").setText(password.getText());
else{
Node n = rootElement.selectSingleNode("//user[@username='"+uname.getText()+"']");
if(n!=null){
MessageDialog dlg = new MessageDialog(window,"Duplicate user",
null,
"You're trying to create a user who already exists!",
SWT.ICON_ERROR,
new String[]{"OK"},
0);
dlg.open();
return;
}
rootElement.addElement("user").addAttribute("username", uname.getText()).addAttribute("password", password.getText());
}
result = true;
}
window.dispose();
}
}