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
021package org.granite.builder.ui;
022
023import java.util.regex.Pattern;
024
025import org.eclipse.swt.SWT;
026import org.eclipse.swt.events.ModifyEvent;
027import org.eclipse.swt.events.ModifyListener;
028import org.eclipse.swt.events.SelectionAdapter;
029import org.eclipse.swt.events.SelectionEvent;
030import org.eclipse.swt.layout.FillLayout;
031import org.eclipse.swt.layout.GridData;
032import org.eclipse.swt.layout.GridLayout;
033import org.eclipse.swt.widgets.Button;
034import org.eclipse.swt.widgets.Composite;
035import org.eclipse.swt.widgets.Control;
036import org.eclipse.swt.widgets.Label;
037import org.eclipse.swt.widgets.List;
038import org.eclipse.swt.widgets.Shell;
039import org.eclipse.swt.widgets.Text;
040import org.eclipse.ui.dialogs.SelectionStatusDialog;
041import org.granite.builder.util.SWTUtil;
042import org.granite.builder.util.StringUtil;
043
044/**
045 * @author Franck WOLFF
046 */
047public 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}