/**
* Copyright (c) 2012 by JP Moresmau
* This code is made available under the terms of the Eclipse Public License,
* version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
*/
package net.sf.eclipsefp.haskell.ui.internal.preferences.editor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.sf.eclipsefp.common.ui.dialog.DialogField;
import net.sf.eclipsefp.common.ui.preferences.overlay.OverlayPreferenceStore;
import net.sf.eclipsefp.haskell.ui.HaskellUIPlugin;
import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.text.TaskTag;
import net.sf.eclipsefp.haskell.ui.internal.util.UITexts;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Preference page for task tags
* @author JP Moresmau
*
*/
public class TaskTagsPP extends AbstractEditorPP {
private final Set<TaskTag> tags=new HashSet<>();
private TableViewer tableViewer;
private Table tTags;
/**
* empty
*/
public TaskTagsPP() {
}
/* (non-Javadoc)
* @see net.sf.eclipsefp.haskell.ui.internal.preferences.editor.AbstractEditorPP#addPreferences(net.sf.eclipsefp.common.ui.preferences.overlay.OverlayPreferenceStore)
*/
@Override
protected void addPreferences( final OverlayPreferenceStore store ) {
store.addStringKey( EDITOR_TASK_TAGS );
store.addStringKey( EDITOR_TASK_TAGS_CASE );
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createContents( final Composite parent ) {
Composite control = new Composite( parent, SWT.NONE );
GridLayout layout = new GridLayout(2,false);
control.setLayout( layout );
Label lText=new Label( control, SWT.NONE );
lText.setText( UITexts.tasks_pref_text );
GridData gdText=new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
gdText.horizontalSpan=2;
lText.setLayoutData( gdText );
tTags=new Table( control, SWT.V_SCROLL | SWT.SINGLE );
GridData gdTable=new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
tTags.setLayoutData( gdTable );
tTags.setHeaderVisible( true );
tTags.setLinesVisible( true );
TableColumn tcTag=new TableColumn( tTags, SWT.LEFT );
tcTag.setText( UITexts.tasks_pref_tag );
tcTag.setWidth(100);
TableColumn tcPriority=new TableColumn( tTags, SWT.LEFT );
tcPriority.setText( UITexts.tasks_pref_priority );
tcPriority.setWidth(100);
tTags.setSortColumn( tcTag );
tTags.setSortDirection( SWT.UP );
SelectionAdapter sel= new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
if (e.widget==tTags.getSortColumn()){
tTags.setSortDirection( tTags.getSortDirection()==SWT.UP?SWT.DOWN:SWT.UP );
} else {
tTags.setSortColumn( (TableColumn )e.widget);
}
update();
}
};
tcTag.addSelectionListener( sel );
tcPriority.addSelectionListener( sel );
tableViewer=new TableViewer( tTags );
tableViewer.setUseHashlookup( true );
tableViewer.setLabelProvider( new TaskTagLabelProvider() );
//tableViewer.setCellModifier( new TaskTagModifier() );
tableViewer.setColumnProperties( new String[]{"tag","priority"} );
tableViewer.setContentProvider( new ArrayContentProvider() );
//tableViewer.setComparator( new WorkbenchViewerComparator() );
Composite cButtons=new Composite(control,SWT.NONE);
GridLayout rl=new GridLayout( 1,true ) ;
cButtons.setLayout(rl);
cButtons.setLayoutData( new GridData(GridData.VERTICAL_ALIGN_BEGINNING) );
Button bNew=new Button(cButtons,SWT.PUSH);
bNew.setText( UITexts.generic_new );
bNew.setLayoutData( new GridData(GridData.HORIZONTAL_ALIGN_FILL) );
bNew.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
TaskTagDialog ttd=new TaskTagDialog( getShell() );
if (ttd.open()==Window.OK){
tags.add( ttd.getTaskTag() );
update();
}
}
} );
final Button bEdit=new Button(cButtons,SWT.PUSH);
bEdit.setText( UITexts.generic_edit );
bEdit.setLayoutData( new GridData(GridData.HORIZONTAL_ALIGN_FILL) );
bEdit.setEnabled( false );
bEdit.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
TaskTag tt=(TaskTag)((IStructuredSelection)tableViewer.getSelection()).getFirstElement();
TaskTagDialog ttd=new TaskTagDialog( getShell(),tt );
if (ttd.open()==Window.OK){
tags.remove( tt ); // name may have changed
tags.add( ttd.getTaskTag() );
update();
}
}
} );
final Button bRemove=new Button(cButtons,SWT.PUSH);
bRemove.setText( UITexts.generic_remove );
bRemove.setLayoutData( new GridData(GridData.HORIZONTAL_ALIGN_FILL) );
bRemove.setEnabled( false );
bRemove.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetSelected(final org.eclipse.swt.events.SelectionEvent e) {
TaskTag tt=(TaskTag)((IStructuredSelection)tableViewer.getSelection()).getFirstElement();
tags.remove( tt );
update();
}
} );
tableViewer.addSelectionChangedListener( new ISelectionChangedListener() {
@Override
public void selectionChanged( final SelectionChangedEvent paramSelectionChangedEvent ) {
boolean sel=((IStructuredSelection)tableViewer.getSelection()).size()==1;
bRemove.setEnabled( sel );
bEdit.setEnabled( sel );
}
} );
DialogField df=createBooleanField( parent, UITexts.tasks_pref_case, EDITOR_TASK_TAGS_CASE );
GridData gdCase=new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
gdCase.horizontalSpan=2;
df.setLayoutData( gdCase );
tags.clear();
tags.addAll(TaskTag.getTasksTags( getPreferenceStore() ));
setInput();
return control;
}
private void setInput(){
List<TaskTag> lTags=new ArrayList<>(tags);
Collections.sort( lTags,new Comparator<TaskTag>() {
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override
public int compare( final TaskTag o1, final TaskTag o2 ) {
int ix=tTags.getSortColumn().getText().equals( UITexts.tasks_pref_tag )?0:1;
String s1=ix==0?o1.getName():o1.getPriority();
String s2=ix==0?o2.getName():o2.getPriority();
return tTags.getSortDirection()==SWT.UP?s1.compareToIgnoreCase( s2 ):s2.compareToIgnoreCase( s1 );
}
} );
tableViewer.setInput( lTags );
}
private void update(){
try {
JSONObject obj=new JSONObject();
JSONArray high=new JSONArray();
obj.put( EDITOR_TASK_TAGS_HIGH, high );
JSONArray normal=new JSONArray();
obj.put( EDITOR_TASK_TAGS_NORMAL, normal );
JSONArray low=new JSONArray();
obj.put( EDITOR_TASK_TAGS_LOW, low );
for (TaskTag tt:tags){
JSONArray arr=tt.getPriority().equals( UITexts.tasks_pref_priority_high )?high
:tt.getPriority().equals( UITexts.tasks_pref_priority_normal )?normal
:low;
arr.put( tt.getName() );
}
getPreferenceStore().setValue( EDITOR_TASK_TAGS, obj.toString() );
setInput();
} catch (JSONException je){
HaskellUIPlugin.log( je );
}
}
/**
* the lavel provider for task tags
* @author JP Moresmau
*
*/
private static class TaskTagLabelProvider extends LabelProvider implements ITableLabelProvider{
@Override
public Image getColumnImage( final Object paramObject, final int paramInt ) {
return null;
}
@Override
public String getColumnText( final Object paramObject, final int paramInt ) {
TaskTag tt=(TaskTag)paramObject;
if (0==paramInt){
return tt.getName();
}
return tt.getPriority();
}
}
/**
* the add/edit dialog for a task tag
* @author JP Moresmau
*
*/
private static class TaskTagDialog extends Dialog {
private TaskTag tt;
public TaskTagDialog( final Shell parentShell ) {
super( parentShell );
}
public TaskTagDialog( final Shell parentShell,final TaskTag tt ) {
super( parentShell );
this.tt=tt.clone();
}
/* (non-Javadoc)
* @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
*/
@Override
protected void configureShell( final Shell newShell ) {
super.configureShell( newShell );
newShell.setText( tt!=null?UITexts.tasks_pref_edit:UITexts.tasks_pref_new );
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
*/
@Override
protected void createButtonsForButtonBar( final Composite parent ) {
super.createButtonsForButtonBar( parent );
update();
}
private void update(){
Button b=getButton( OK );
if (b!=null && !b.isDisposed()){
b.setEnabled( tt!=null && tt.getName()!=null && tt.getName().length()>0 && tt.getPriority()!=null && tt.getPriority().length()>0 );
}
}
/**
* @return the tt
*/
public TaskTag getTaskTag() {
return tt;
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createDialogArea( final Composite parent ) {
Composite control= (Composite)super.createDialogArea( parent );
GridLayout layout = new GridLayout(2,false);
control.setLayout( layout );
Label lTag=new Label(control,SWT.NONE);
lTag.setText( UITexts.tasks_pref_tag );
final Text tTag=new Text(control, SWT.BORDER);
tTag.setLayoutData( new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL) );
if (tt!=null){
tTag.setText( tt.getName() );
}
Label lPriority=new Label(control,SWT.NONE);
lPriority.setText( UITexts.tasks_pref_priority );
final Combo cPriority=new Combo(control,SWT.READ_ONLY);
cPriority.setItems( new String[]{UITexts.tasks_pref_priority_high,UITexts.tasks_pref_priority_normal,UITexts.tasks_pref_priority_low} );
cPriority.setLayoutData( new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL) );
if (tt!=null){
for (int a=0;a<cPriority.getItemCount();a++){
if (cPriority.getItem( a ).equals(tt.getPriority())){
cPriority.select( a );
break;
}
}
} else {
cPriority.select( 1 );
tt=new TaskTag( tTag.getText(), cPriority.getItem( 1 ) );
}
tTag.addModifyListener( new ModifyListener() {
@Override
public void modifyText( final ModifyEvent arg0 ) {
if (tt==null){
tt=new TaskTag( tTag.getText(), cPriority.getItem( cPriority.getSelectionIndex() ) );
} else {
tt.setName(tTag.getText());
}
update();
}
} );
cPriority.addSelectionListener( new SelectionAdapter() {
/* (non-Javadoc)
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
@Override
public void widgetSelected( final SelectionEvent e ) {
if (tt==null){
tt=new TaskTag( tTag.getText(), cPriority.getItem( cPriority.getSelectionIndex() ) );
} else {
tt.setPriority(cPriority.getItem( cPriority.getSelectionIndex() ));
}
update();
}
} );
return control;
}
}
}