001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.builder.ui;
022    
023    import java.util.regex.Pattern;
024    
025    import org.eclipse.swt.SWT;
026    import org.eclipse.swt.events.ModifyEvent;
027    import org.eclipse.swt.events.ModifyListener;
028    import org.eclipse.swt.events.SelectionAdapter;
029    import org.eclipse.swt.events.SelectionEvent;
030    import org.eclipse.swt.layout.FillLayout;
031    import org.eclipse.swt.layout.GridData;
032    import org.eclipse.swt.layout.GridLayout;
033    import org.eclipse.swt.widgets.Button;
034    import org.eclipse.swt.widgets.Composite;
035    import org.eclipse.swt.widgets.Control;
036    import org.eclipse.swt.widgets.Label;
037    import org.eclipse.swt.widgets.List;
038    import org.eclipse.swt.widgets.Shell;
039    import org.eclipse.swt.widgets.Text;
040    import org.eclipse.ui.dialogs.SelectionStatusDialog;
041    import org.granite.builder.util.SWTUtil;
042    import org.granite.builder.util.StringUtil;
043    
044    /**
045     * @author Franck WOLFF
046     */
047    public class IncludeExcludeOutputDialog extends SelectionStatusDialog {
048    
049            private static final Pattern INCLUDE_PATTERN = Pattern.compile("[\\w\\*\\.\\$\\?/]+(\\[(\\w+=\\w+)(,\\w+=\\w+)*\\])?");
050            private static final Pattern EXCLUDE_PATTERN = Pattern.compile("[\\w\\*\\.\\$\\?/]+");
051            private static final Pattern OUTPUT_PATTERN = Pattern.compile("[\\w\\-\\.\\/]*");
052            
053            private final String[] initialValues;
054            
055            private List includes = null;
056            private List excludes = null;
057            private Text output = null;
058            private Text baseOutput = null; 
059            
060            public IncludeExcludeOutputDialog(Shell parent, String[] initialValues) {
061                    super(parent);
062                    
063                    if (initialValues == null)
064                            initialValues = new String[3];
065                    else if (initialValues.length != 3)
066                            throw new IllegalArgumentException("Bad initialValues length: " + initialValues.length);
067                    for (int i = 0; i < initialValues.length; i++) {
068                            if (initialValues[i] == null)
069                                    initialValues[i] = "";
070                    }
071                    
072                    this.initialValues = initialValues;
073                    
074                    setSelectionResult(null);
075                    setStatusLineAboveButtons(true);
076    
077                    int shellStyle = getShellStyle();
078                    setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
079            }
080            
081            @Override
082            protected void cancelPressed() {
083                    setSelectionResult(initialValues);
084                    super.cancelPressed();
085            }
086            
087            @Override
088            protected void computeResult() {
089                    String[] result = new String[3];
090                    
091                    StringBuilder sb = new StringBuilder();
092                    for (String value : includes.getItems()) {
093                            if (sb.length() > 0)
094                                    sb.append(';');
095                            sb.append(value);
096                    }
097                    result[0] = sb.toString();
098                    
099                    sb.setLength(0);
100                    for (String value : excludes.getItems()) {
101                            if (sb.length() > 0)
102                                    sb.append(';');
103                            sb.append(value);
104                    }
105                    result[1] = sb.toString();
106                    
107                    sb.setLength(0);
108                    sb.append(output.getText()).append(';').append(baseOutput.getText());
109                    result[2] = sb.toString();
110                    
111                    setSelectionResult(result);
112            }
113            
114            @Override
115            protected Control createDialogArea(Composite parent) {
116            final Composite composite = (Composite)super.createDialogArea(parent);
117                    GridData data = new GridData(GridData.FILL_BOTH);
118                    data.widthHint = convertWidthInCharsToPixels(70);
119                    data.heightHint = convertHeightInCharsToPixels(26);
120                    composite.setLayoutData(data);
121                    composite.setLayout(new GridLayout(2, false));
122                    
123                    Label label = new Label(composite, SWT.NONE);
124                    label.setText("Inclusion Patterns:");
125                    label.setLayoutData(SWTUtil.newGridData(SWT.NONE, 2));
126            
127                    includes = new List(composite, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
128                    includes.setLayoutData(new GridData(GridData.FILL_BOTH));
129                    for (String s : StringUtil.split(initialValues[0], ';')) {
130                            if (s.length() != 0)
131                                    includes.add(s);
132                    }
133                    
134                    Composite includesButtons = new Composite(composite, SWT.NONE);
135                    includesButtons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
136                    includesButtons.setLayout(new FillLayout(SWT.VERTICAL));
137                    
138                    SWTUtil.newButton(includesButtons, "Add...", true, new SelectionAdapter() {
139                            @Override
140                            public void widgetSelected(SelectionEvent e) {
141                                    String pattern = Dialogs.prompt(
142                                            getShell(),
143                                            "Add Inclusion Pattern",
144                                            "Allowed wildcards are '?', '*' and '**'",
145                                            null,
146                                            INCLUDE_PATTERN
147                                    );
148                                    if (pattern != null && pattern.trim().length() > 0)
149                                            includes.add(pattern.trim());
150                            }
151                    });
152                    final Button includesEditButton = SWTUtil.newButton(includesButtons, "Edit...", false, new SelectionAdapter() {
153                            @Override
154                            public void widgetSelected(SelectionEvent e) {
155                                    int selectedIndex = includes.getSelectionIndex();
156                                    String pattern = Dialogs.prompt(
157                                            getShell(),
158                                            "Edit Inclusion Pattern",
159                                            "Allowed wildcards are '?', '*' and '**'",
160                                            includes.getItem(selectedIndex),
161                                            INCLUDE_PATTERN
162                                    );
163                                    includes.setItem(selectedIndex, pattern.trim());
164                            }
165                    });
166                    final Button includesRemoveButton = SWTUtil.newButton(includesButtons, "Remove", false, new SelectionAdapter() {
167                            @Override
168                            public void widgetSelected(SelectionEvent e) {
169                                    int selectedIndex = includes.getSelectionIndex();
170                                    includes.remove(selectedIndex);
171                                    
172                                    if (includes.getItemCount() <= 0) {
173                                            ((Button)e.getSource()).setEnabled(false);
174                                            includesEditButton.setEnabled(false);
175                                    }
176                                    else if (selectedIndex < includes.getItemCount())
177                                            includes.setSelection(selectedIndex);
178                                    else
179                                            includes.setSelection(selectedIndex - 1);
180                            }
181                    });
182                    
183                    includes.addSelectionListener(new SelectionAdapter() {
184                            @Override
185                            public void widgetSelected(SelectionEvent event) {
186                                    includesRemoveButton.setEnabled(true);
187                                    includesEditButton.setEnabled(true);
188                            }
189                    });
190                    
191                    label = new Label(composite, SWT.NONE);
192                    label.setText("Exclusion Patterns:");
193                    label.setLayoutData(SWTUtil.newGridData(SWT.NONE, 2));
194            
195                    excludes = new List(composite, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
196                    excludes.setLayoutData(new GridData(GridData.FILL_BOTH));
197                    for (String s : StringUtil.split(initialValues[1], ';')) {
198                            if (s.length() != 0)
199                                    excludes.add(s);
200                    }
201                    
202                    Composite excludesButtons = new Composite(composite, SWT.NONE);
203                    excludesButtons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
204                    excludesButtons.setLayout(new FillLayout(SWT.VERTICAL));
205                    
206                    SWTUtil.newButton(excludesButtons, "Add...", true, new SelectionAdapter() {
207                            @Override
208                            public void widgetSelected(SelectionEvent e) {
209                                    String pattern = Dialogs.prompt(
210                                            getShell(),
211                                            "Add Exclusion Pattern",
212                                            "Allowed wildcards are '?', '*' and '**'",
213                                            null,
214                                            EXCLUDE_PATTERN
215                                    );
216                                    if (pattern != null && pattern.trim().length() > 0)
217                                            excludes.add(pattern.trim());
218                            }
219                    });
220                    final Button excludesEditButton = SWTUtil.newButton(excludesButtons, "Edit...", false, new SelectionAdapter() {
221                            @Override
222                            public void widgetSelected(SelectionEvent e) {
223                                    int selectedIndex = excludes.getSelectionIndex();
224                                    String pattern = Dialogs.prompt(
225                                            getShell(),
226                                            "Edit Exclusion Pattern",
227                                            "Allowed wildcards are '?', '*' and '**'",
228                                            excludes.getItem(selectedIndex),
229                                            EXCLUDE_PATTERN
230                                    );
231                                    excludes.setItem(selectedIndex, pattern.trim());
232                            }
233                    });
234                    final Button excludesRemoveButton = SWTUtil.newButton(excludesButtons, "Remove", false, new SelectionAdapter() {
235                            @Override
236                            public void widgetSelected(SelectionEvent e) {
237                                    int selectedIndex = excludes.getSelectionIndex();
238                                    excludes.remove(selectedIndex);
239                                    
240                                    if (excludes.getItemCount() <= 0) {
241                                            ((Button)e.getSource()).setEnabled(false);
242                                            excludesEditButton.setEnabled(false);
243                                    }
244                                    else if (selectedIndex < excludes.getItemCount())
245                                            excludes.setSelection(selectedIndex);
246                                    else
247                                            excludes.setSelection(selectedIndex - 1);
248                            }
249                    });
250                    
251                    excludes.addSelectionListener(new SelectionAdapter() {
252                            @Override
253                            public void widgetSelected(SelectionEvent event) {
254                                    excludesRemoveButton.setEnabled(true);
255                                    excludesEditButton.setEnabled(true);
256                            }
257                    });
258    
259                    String[] outputs = StringUtil.split(initialValues[2], ';');
260                    
261                    label = new Label(composite, SWT.NONE);
262                    label.setText("Output Directory (relative to project dir):");
263                    label.setLayoutData(SWTUtil.newGridData(SWT.NONE, 2));
264            
265            output = new Text(composite, SWT.BORDER);
266            output.setLayoutData(SWTUtil.newGridData(GridData.FILL_HORIZONTAL, 2));
267            if (outputs.length > 0)
268                    output.setText(outputs[0]);
269            output.addModifyListener(new ModifyListener() {
270                            @Override
271                            public void modifyText(ModifyEvent event) {
272                                    if (OUTPUT_PATTERN.matcher(output.getText()).matches()) {
273                                            output.setBackground(SWTUtil.getColor(getShell().getDisplay(), SWTUtil.WHITE));
274                                            getOkButton().setEnabled(true);
275                                    }
276                                    else {
277                                            output.setBackground(SWTUtil.getColor(getShell().getDisplay(), SWTUtil.LIGHT_RED));
278                                            getOkButton().setEnabled(false);
279                                    }
280                            }
281                    });
282    
283            label = new Label(composite, SWT.NONE);
284            label.setText("Base Output Directory (optional, default to output above):");
285            label.setLayoutData(SWTUtil.newGridData(SWT.NONE, 2));
286            
287            baseOutput = new Text(composite, SWT.BORDER);
288            baseOutput.setLayoutData(SWTUtil.newGridData(GridData.FILL_HORIZONTAL, 2));
289            if (outputs.length > 1)
290                    baseOutput.setText(outputs[1]);
291            baseOutput.addModifyListener(new ModifyListener() {
292                            @Override
293                            public void modifyText(ModifyEvent event) {
294                                    if (OUTPUT_PATTERN.matcher(baseOutput.getText()).matches()) {
295                                            baseOutput.setBackground(SWTUtil.getColor(getShell().getDisplay(), SWTUtil.WHITE));
296                                            getOkButton().setEnabled(true);
297                                    }
298                                    else {
299                                            baseOutput.setBackground(SWTUtil.getColor(getShell().getDisplay(), SWTUtil.LIGHT_RED));
300                                            getOkButton().setEnabled(false);
301                                    }
302                            }
303                    });
304    
305            applyDialogFont(composite);
306    
307            return composite;
308            }
309    }