/* Copyright (C) 2009 Mobile Sorcery AB
This program is free software; you can redistribute it and/or modify it
under the terms of the Eclipse Public License v1.0.
This program 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 Eclipse Public License v1.0 for
more details.
You should have received a copy of the Eclipse Public License v1.0 along
with this program. It is also available at http://www.eclipse.org/legal/epl-v10.html
*/
package com.mobilesorcery.sdk.ui.targetphone.internal;
import java.text.MessageFormat;
import java.util.HashMap;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import com.mobilesorcery.sdk.core.MoSyncTool;
import com.mobilesorcery.sdk.profiles.IDeviceFilter;
import com.mobilesorcery.sdk.profiles.IProfile;
import com.mobilesorcery.sdk.profiles.ITargetProfileProvider;
import com.mobilesorcery.sdk.profiles.filter.CompositeDeviceFilter;
import com.mobilesorcery.sdk.profiles.filter.EmulatorDeviceFilter;
import com.mobilesorcery.sdk.profiles.ui.DeviceViewerFilter;
import com.mobilesorcery.sdk.ui.Note;
import com.mobilesorcery.sdk.ui.ProfileContentProvider;
import com.mobilesorcery.sdk.ui.ProfileLabelProvider;
import com.mobilesorcery.sdk.ui.UIUtils;
import com.mobilesorcery.sdk.ui.targetphone.ITargetPhone;
import com.mobilesorcery.sdk.ui.targetphone.ITargetPhoneTransport;
import com.mobilesorcery.sdk.ui.targetphone.TargetPhonePlugin;
public class EditDeviceListDialog extends Dialog {
public class TargetDeviceLabelProvider extends LabelProvider {
@Override
public String getText(Object o) {
ITargetPhone t = (ITargetPhone) o;
ITargetPhoneTransport tt = t.getTransport();
return MessageFormat.format("{0} [{1}]", t.getName(), tt.getDescription(""));
}
}
private ComboViewer deviceList;
private TreeViewer preferredProfile;
private ITargetPhone initialTargetPhone;
private boolean fixedDevice;
private final HashMap<ITargetPhone, IProfile> pendingChanges = new HashMap<ITargetPhone, IProfile>();
private Integer profileManagerType;
public EditDeviceListDialog(Shell parentShell) {
super(parentShell);
}
public void setInitialTargetPhone(ITargetPhone initialTargetPhone) {
this.initialTargetPhone = initialTargetPhone;
}
@Override
public Control createDialogArea(Composite parent) {
getShell().setText("Select Preferred Profile");
ITargetPhone initialTargetPhone = this.initialTargetPhone == null ? TargetPhonePlugin.getDefault().getCurrentlySelectedPhone()
: this.initialTargetPhone;
Composite main = (Composite) super.createDialogArea(parent);
Composite contents = new Composite(main, SWT.NONE);
contents.setLayout(new GridLayout(1, false));
if (!fixedDevice) {
deviceList = new ComboViewer(contents, SWT.BORDER | SWT.READ_ONLY);
deviceList.setContentProvider(new ArrayContentProvider());
deviceList.setLabelProvider(new TargetDeviceLabelProvider());
deviceList.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
updateFilter();
updateUI(null, false);
}
});
deviceList.getCombo().setLayoutData(new GridData(UIUtils.getDefaultFieldSize(), SWT.DEFAULT));
Link clear = new Link(contents, SWT.NONE);
clear.setText("<a>Clear History</a>");
clear.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false));
clear.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
clearDeviceList(getShell());
updateUI(null, true);
}
});
}
Label instructions = new Label(contents, SWT.NONE | SWT.WRAP);
String instructionMsg = "Click to select new target profile";
instructions.setText(instructionMsg);
if (getProfileManagerType() == MoSyncTool.LEGACY_PROFILE_TYPE) {
Note note = new Note(contents, SWT.NONE);
note.setText("NOTE:\nThe selected project uses a (legacy) device based profile database.\nThis is why this list looks different than for platform based profile databases.");
note.setLayoutData(new GridData(UIUtils.getDefaultFieldSize(), SWT.DEFAULT));
}
preferredProfile = new TreeViewer(contents, SWT.SINGLE | SWT.BORDER);
ProfileLabelProvider labelProvider = new ProfileLabelProvider(SWT.NONE);
labelProvider.setTargetProfileProvider(new ITargetProfileProvider() {
@Override
public IProfile getTargetProfile() {
return getCurrentPreferredProfile();
}
});
preferredProfile.setLabelProvider(labelProvider);
final ProfileContentProvider contentProvider = new ProfileContentProvider();
preferredProfile.setContentProvider(contentProvider);
preferredProfile.getControl().setLayoutData(new GridData(UIUtils.getDefaultFieldSize(), UIUtils.getDefaultListHeight()));
preferredProfile.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(DoubleClickEvent event) {
selectNewProfile(event.getSelection());
okPressed();
}
});
preferredProfile.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
selectNewProfile(event.getSelection());
}
});
updateFilter();
updateUI(initialTargetPhone, true);
return contents;
}
private void selectNewProfile(ISelection selection) {
Object element = ((IStructuredSelection) selection).getFirstElement();
if (element instanceof IProfile) {
IProfile profile = (IProfile) element;
ITargetPhone currentTargetPhone = getSelectedTargetPhone();
if (currentTargetPhone != null) {
pendingChanges.put(currentTargetPhone, profile);
}
updateButtons();
preferredProfile.refresh();
}
}
/**
* Sets a fixed device for this dialog (resulting in no visible device
* selector).
*
* @param b
*/
public void setFixedDevice(boolean fixedDevice) {
this.fixedDevice = fixedDevice;
}
protected ITargetPhone getSelectedTargetPhone() {
if (fixedDevice) {
return initialTargetPhone;
} else {
ITargetPhone selectedPhone = (ITargetPhone) ((IStructuredSelection) deviceList.getSelection()).getFirstElement();
return selectedPhone;
}
}
protected void updateFilter() {
IDeviceFilter emulatorFilter = new EmulatorDeviceFilter(EmulatorDeviceFilter.EXCLUDE_EMULATORS);
ITargetPhone phone = getSelectedTargetPhone();
IDeviceFilter targetPhoneAcceptedProfiles = phone == null ? null : phone.getTransport().getAcceptedProfiles();
IDeviceFilter filter = targetPhoneAcceptedProfiles == null ? emulatorFilter : new CompositeDeviceFilter(new IDeviceFilter[] { emulatorFilter,
targetPhoneAcceptedProfiles });
preferredProfile.setInput(MoSyncTool.getDefault().getProfileManager(getProfileManagerType()).getVendors(filter));
preferredProfile.setFilters(new ViewerFilter[] { new DeviceViewerFilter(filter) });
}
@Override
public void createButtonsForButtonBar(Composite parent) {
Button okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
updateButtons();
}
protected IProfile getCurrentPreferredProfile() {
IProfile profile = null;
ITargetPhone selectedPhone = getSelectedTargetPhone();
if (selectedPhone != null) {
profile = pendingChanges.get(selectedPhone);
if (profile == null) {
profile = selectedPhone.getPreferredProfile(getProfileManagerType());
}
}
return profile;
}
private int getProfileManagerType() {
if (profileManagerType == null) {
profileManagerType = TargetPhonePlugin.getDefault().getCurrentProfileManagerType();
}
return profileManagerType;
}
protected void updateUI(ITargetPhone changeToTargetPhone, boolean reloadPhones) {
if (!fixedDevice) {
if (reloadPhones) {
deviceList.setInput(TargetPhonePlugin.getDefault().getSelectedTargetPhoneHistory().toArray());
}
if (changeToTargetPhone != null) {
deviceList.setSelection(new StructuredSelection(changeToTargetPhone), true);
}
}
IProfile profile = getCurrentPreferredProfile();
preferredProfile.refresh();
preferredProfile.setSelection(profile == null ? new StructuredSelection() : new StructuredSelection(profile), true);
updateButtons();
}
private void updateButtons() {
Button okButton = getButton(IDialogConstants.OK_ID);
if (okButton != null) {
okButton.setEnabled(okButtonEnabled());
}
}
private boolean okButtonEnabled() {
IProfile profile = getCurrentPreferredProfile();
return profile != null;
}
@Override
public void okPressed() {
if (okButtonEnabled()) {
commitPendingChanges();
super.okPressed();
}
}
private void commitPendingChanges() {
for (ITargetPhone phone : pendingChanges.keySet()) {
IProfile newProfile = pendingChanges.get(phone);
phone.setPreferredProfile(getProfileManagerType(), newProfile);
}
}
protected void clearDeviceList(Shell parent) {
if (MessageDialog.openConfirm(parent, "Are you sure?", "This will clear the list of target devices -- are you sure?")) {
TargetPhonePlugin.getDefault().clearHistory();
close();
}
}
}