/**
* This file is part of HIDB2.
*
* HIDB2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HIDB2 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 Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser Public License
* along with HIDB2. If not, see <http://www.gnu.org/licenses/>.
*/
package hidb2.gui.util;
import static hidb2.kern.AttrType.T_Double;
import static hidb2.kern.AttrType.T_Integer;
import hidb2.gui.Application;
import hidb2.kern.AttrEnumItemChecker;
import hidb2.kern.AttrImage;
import hidb2.kern.AttrType;
import hidb2.kern.Attribut;
import hidb2.kern.DataPath;
import hidb2.kern.EnumItem;
import hidb2.kern.HIDBConst;
import hidb2.kern.StatusCycle;
import java.util.BitSet;
import java.util.Date;
import java.util.List;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColorCellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.DialogCellEditor;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
/**
* Conviniences functions for GUI creation. (Not OO Design)
*
*/
public class Parts implements HIDBConst
{
/**
* This method create a text with a label for text input.
* Size if set to 200 points.
*/
private final static Text createInternal(Composite _parent, String label, boolean editable, Composite c, int size)
{
GridData gridData1 = new GridData();
gridData1.horizontalSpan = 2;
gridData1.widthHint = size;
Composite comp = c;
if (comp == null)
{
comp = new Composite(_parent, SWT.NONE);
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 3;
comp.setLayout(gridLayout);
}
Label lab = new Label(comp, SWT.NONE);
lab.setText(label);
Text txt = new Text(comp, SWT.BORDER);
txt.setEditable(editable);
txt.setLayoutData(gridData1);
return txt;
}
/**
* This method create a text with a label for text input.
* Size if set to 200 points.
*/
public final static Text createText(Composite _parent, String label, boolean editable, Composite c)
{
return createInternal(_parent, label, editable, c, 200);
}
/**
* This method create a text with a label for text input.
* Size if set to 100 points.
*/
public final static Text createNum(Composite _parent, String label, boolean editable, Composite c)
{
return createInternal(_parent, label, editable, c, 100);
}
public final static Section createStaticSection(FormToolkit toolkit, Composite parent, String text)
{
Section section = toolkit.createSection(parent, ExpandableComposite.TITLE_BAR);
section.clientVerticalSpacing = FormLayoutFactory.SECTION_HEADER_VERTICAL_SPACING;
section.setText(text);
section.setLayout(FormLayoutFactory.createClearTableWrapLayout(false, 1));
TableWrapData data = new TableWrapData(TableWrapData.FILL_GRAB);
section.setLayoutData(data);
return section;
}
public final static Composite createStaticSectionClient(FormToolkit toolkit, Composite parent)
{
Composite container = toolkit.createComposite(parent, SWT.NONE);
container.setLayout(FormLayoutFactory.createSectionClientTableWrapLayout(false, 2));
TableWrapData data = new TableWrapData(TableWrapData.FILL_GRAB);
container.setLayoutData(data);
return container;
}
public final static FormText createClient(Composite section, String content, FormToolkit toolkit)
{
FormText text = toolkit.createFormText(section, true);
try
{
text.setText(content, false, false);
}
catch (SWTException e)
{
text.setText(e.getMessage(), false, false);
}
return text;
}
/**
* Create a selectable pulldown menu.
*
* @param toolBar Parent tool bar
* @param title Initial title
* @param labels List of labels
* @param masterIndex Index of the item that reset other ones. Value -1 desactives the function
* @param listener Listener called at each click
* @return The DROP_DOWN tool item
*/
public final static ToolItem createPullDown(ToolBar toolBar, String title, String[] labels, int masterIndex,
SelectionListener listener)
{
ToolItem toolItem4 = new ToolItem(toolBar, SWT.DROP_DOWN);
toolItem4.setText(title);
DropdownSelectionListener listenerOne = new DropdownSelectionListener(toolItem4, masterIndex, listener);
for (int i = 0; i < labels.length; i++)
{
listenerOne.add(labels[i]);
}
toolItem4.addSelectionListener(listenerOne);
return toolItem4;
}
public final static String formatFileSize(long t)
{
if (t < 1024L)
{
return (Long.toString(t) + " o");
}
else
{
t /= 1024L;
if (t < 1024L)
{
return (Long.toString(t) + " ko");
}
else
{
t /= 1024L;
return (Long.toString(t) + " Mo");
}
}
}
/**
* Create the Table Cell Editor for the given attribute.
* @param table Future Parent Table
* @return
*/
public static CellEditor createCellEditor(final Attribut attr, final Table table)
{
CellEditor cellEdt = null;
switch (attr.getType())
{
case T_Integer:
cellEdt = new NumericCellEditor(table, SWT.SINGLE, T_Integer);
break;
case T_String:
cellEdt = new TextCellEditor(table);
break;
case T_Boolean:
cellEdt = new CheckboxCellEditor(table);
break;
case T_Double:
cellEdt = new NumericCellEditor(table, SWT.SINGLE, T_Double);
break;
case T_Date:
cellEdt = createDateTimeEditor(table, SWT.CALENDAR);
break;
case T_Time:
cellEdt = createDateTimeEditor(table, SWT.TIME);
break;
case T_TimeStamp:
cellEdt = createDateTimeEditor(table, SWT.CALENDAR | SWT.TIME);
break;
case T_Color: // Color
cellEdt = new ColorCellEditor(table);
break;
case T_RefList:
AttrEnumItemChecker aei = (AttrEnumItemChecker) attr.getChecker();
List<EnumItem> lstEnumItems = aei.getLstEnumItem();
String[] tabRefListNames = new String[lstEnumItems.size()];
int ii = 0;
for (EnumItem eu : lstEnumItems)
{
tabRefListNames[ii] = eu.getVisualLabel();
ii++;
}
cellEdt = new ComboBoxCellEditor(table, tabRefListNames, SWT.READ_ONLY);
break;
case T_TypeEnum:
AttrType[] vt = AttrType.values();
int nbT = 0;
for (AttrType at : vt)
{
if (at.id > 0)
nbT++;
}
String[] tabTypesNames = new String[nbT];
int i = 0;
for (AttrType at : vt)
{
if (at.id > 0)
{
tabTypesNames[i++] = at.name;
}
}
cellEdt = new ComboBoxCellEditor(table, tabTypesNames, SWT.READ_ONLY);
// PoserMeshedObject pm = (PoserMeshedObject) po;
// PoserFile pf = pm.getPoserFile();
// List<String> ls = pf.getLstFigProp();
// int noit = ls.indexOf(p);
// ((Combo) _widget).setItems(ls.toArray(new String[ls.size()]));
// ((Combo) _widget).select((noit > 0) ? noit : 0);
break;
case T_Image:
// TODO : Begin with a simple file selector
cellEdt = new DialogCellEditor(table)
{
FileDialog _fd;
@Override
protected Object openDialogBox(Control cellEditorWindow)
{
AttrImage ai = (AttrImage) getValue();
// Set initial values (directory)
if (_fd == null)
{
_fd = new FileDialog(cellEditorWindow.getShell());
}
if (ai == null)
{
ai = new AttrImage();
ai.setChecker(attr.getChecker());
}
String fullname = ai.getAbsolutePath();
if (fullname != null)
{
_fd.setFileName(fullname);
}
fullname = _fd.open();
if (fullname != null)
{
// Find & Use correct DataPath
DataPath rDp = Application.getDataStore().findDataPath(fullname);
ai.setDataPath(rDp);
if (rDp != null)
{
fullname = fullname.substring(rDp.getPath().length());
}
ai.setValue(fullname);
if (ai.getStatus() == StatusCycle.UNCHANGED)
{
ai.setStatus(StatusCycle.MODIFIED);
}
}
else
{
ai = null;
}
return ai;
}
};
break;
default:
throw new IllegalArgumentException();
}
return cellEdt;
}
public static DialogCellEditor createDateTimeEditor(Table table, final int style)
{
return new DialogCellEditor(table)
{
@Override
protected Object openDialogBox(Control cellEditorWindow)
{
DlgDateTime dlg = new DlgDateTime(cellEditorWindow.getShell(), style);
Date ai = (Date) getValue();
Object r = dlg.open(ai);
return r;
}
};
}
}
class DropdownSelectionListener extends SelectionAdapter
{
private Menu menu;
private SelectionListener _listener;
private int _masterIndex;
public DropdownSelectionListener(ToolItem dropdown, int masterIndex, SelectionListener listener)
{
menu = new Menu(dropdown.getParent().getShell());
_masterIndex = masterIndex;
_listener = listener;
}
public void add(String item)
{
MenuItem menuItem = new MenuItem(menu, SWT.CHECK);
menuItem.setText(item);
menuItem.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent event)
{
// Compile the status of item in a bitfield transmitted via the data attribut of the event
MenuItem[] tabit = menu.getItems();
int l = tabit.length;
BitSet bs = new BitSet(l);
if (_masterIndex >= 0)
{
if (((MenuItem) event.widget == tabit[_masterIndex]) && tabit[_masterIndex].getSelection())
{
for (int i = 0; i < l; i++)
{
if (i != _masterIndex)
{
tabit[i].setSelection(false);
}
}
bs.set(_masterIndex);
}
else
{
tabit[_masterIndex].setSelection(false);
for (int i = 0; i < l; i++)
{
bs.set(i, tabit[i].getSelection());
}
}
}
else
{
for (int i = 0; i < l; i++)
{
bs.set(i, tabit[i].getSelection());
}
}
event.data = bs;
_listener.widgetSelected(event);
}
});
}
public void widgetSelected(SelectionEvent event)
{
if (event.detail == SWT.ARROW)
{
ToolItem item = (ToolItem) event.widget;
Rectangle rect = item.getBounds();
Point pt = item.getParent().toDisplay(new Point(rect.x, rect.y));
menu.setLocation(pt.x, pt.y + rect.height);
menu.setVisible(true);
}
}
}