source: trunk/org.modelica.mdt/src/org/modelica/mdt/NewClassWizard.java @ 34

Last change on this file since 34 was 34, checked in by boris, 19 years ago
  • added connector to class type that don't get a equations block generated
  • added 'include initial equation block' functionality to new class wizard
File size: 12.2 KB
Line 
1package org.modelica.mdt;
2
3
4import java.io.ByteArrayInputStream;
5import java.io.IOException;
6import java.io.InputStream;
7import java.lang.reflect.InvocationTargetException;
8import java.util.regex.Pattern;
9
10import org.eclipse.core.resources.IContainer;
11import org.eclipse.core.resources.IFile;
12import org.eclipse.core.resources.IResource;
13import org.eclipse.core.resources.IWorkspaceRoot;
14import org.eclipse.core.resources.ResourcesPlugin;
15import org.eclipse.core.runtime.CoreException;
16import org.eclipse.core.runtime.IPath;
17import org.eclipse.core.runtime.IProgressMonitor;
18import org.eclipse.core.runtime.Path;
19import org.eclipse.jface.dialogs.DialogPage;
20import org.eclipse.jface.dialogs.MessageDialog;
21import org.eclipse.jface.operation.IRunnableWithProgress;
22import org.eclipse.jface.viewers.IStructuredSelection;
23import org.eclipse.jface.wizard.Wizard;
24import org.eclipse.jface.wizard.WizardPage;
25import org.eclipse.swt.SWT;
26import org.eclipse.swt.events.ModifyEvent;
27import org.eclipse.swt.events.ModifyListener;
28import org.eclipse.swt.events.SelectionAdapter;
29import org.eclipse.swt.events.SelectionEvent;
30import org.eclipse.swt.events.SelectionListener;
31import org.eclipse.swt.layout.GridData;
32import org.eclipse.swt.layout.GridLayout;
33import org.eclipse.swt.widgets.Combo;
34import org.eclipse.swt.widgets.Composite;
35import org.eclipse.swt.widgets.Label;
36import org.eclipse.swt.widgets.Text;
37import org.eclipse.swt.widgets.Button;
38import org.eclipse.ui.INewWizard;
39import org.eclipse.ui.IWorkbench;
40import org.eclipse.ui.IWorkbenchPage;
41import org.eclipse.ui.PartInitException;
42import org.eclipse.ui.PlatformUI;
43import org.eclipse.ui.dialogs.ContainerSelectionDialog;
44import org.eclipse.ui.ide.IDE;
45
46public class NewClassWizard extends Wizard implements INewWizard
47{
48    public class NewClassPage extends WizardPage
49    {
50        private Text sourceFolder;
51        private Text className;
52        private Combo classType;
53        private Button initialEquation;
54   
55        private IPath selection = null;
56       
57       
58        /* regexp pattern of a valid modelica class name */
59        //TODO add complete regexp for modelcia class name
60        // see modelica specification page 9 (and perhaps some other pages as well)
61        // http://www.modelica.org/documents/ModelicaSpec22.pdf
62        Pattern classNamePattern = Pattern.compile("[a-zA-Z]\\w*");
63       
64        private boolean classNameValid = false;
65        private boolean sourceFolderValid = false;     
66       
67        public NewClassPage()
68        {
69            super("");
70        }
71
72        public void createControl(Composite parent)
73        {
74            setPageComplete(false);
75            /*
76             * configure description of this page
77             */
78            setTitle("Modelica Class");
79            setDescription("Create a new Modelica class.");
80           
81            // TODO set image descriptor           
82            //setImageDescriptor(...);
83           
84            /*
85             * setup widgets for this page
86             */
87            Composite composite= new Composite(parent, SWT.NONE);
88            setControl(composite);
89            composite.setFont(parent.getFont());
90           
91            GridLayout layout = new GridLayout();
92            layout.numColumns = 3;
93            composite.setLayout(layout);
94           
95            GridData gd;
96
97            /* source folder field */
98            Label l = new Label(composite, SWT.LEFT | SWT.WRAP);
99            l.setText("Source folder:");
100            gd = new GridData();
101            gd.horizontalAlignment = GridData.BEGINNING;
102            l.setLayoutData(gd);
103           
104            sourceFolder = new Text(composite,  SWT.SINGLE | SWT.BORDER);
105            gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
106            sourceFolder.setLayoutData(gd);
107            setSourceFolder(selection);
108           
109            sourceFolder.addModifyListener(new ModifyListener()
110            {
111                    /* check if entered path exists */
112                    public void modifyText(ModifyEvent e)
113                    {
114                        sourceFolderChanged();
115                    }
116            });
117
118
119            Button b = new Button(composite, SWT.PUSH);
120            b.setText("Browse...");
121            gd = new GridData();
122            gd.horizontalAlignment = GridData.END;
123            b.setLayoutData(gd);
124            b.addSelectionListener(new SelectionAdapter()
125            {
126                public void widgetSelected(SelectionEvent e)
127                {
128                    handleBrowse();
129                }
130            });
131
132           
133            /* class name field */
134            l = new Label(composite, SWT.LEFT | SWT.WRAP);
135            l.setText("Name:");
136            gd = new GridData();
137            gd.horizontalAlignment = GridData.BEGINNING;
138            l.setLayoutData(gd);
139           
140            className = new Text(composite,  SWT.SINGLE | SWT.BORDER);
141            gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
142            gd.horizontalSpan = 2;
143            className.setLayoutData(gd);
144
145            className.addModifyListener(new ModifyListener()
146            {
147                /* check if entered classname is valid */
148                public void modifyText(ModifyEvent e)
149                {
150                    if (!isLegalClassName(className.getText()))
151                    {
152                        classNameValid  = false;
153                        updateStatus("Class name is not valid. Illegal identifier.",
154                                    DialogPage.WARNING);
155                    }
156                    else
157                    {
158                        classNameValid  = true;
159                        updateStatus(null, DialogPage.NONE);
160                    }
161                }
162            });
163            className.setFocus();
164
165            /* class type field */
166            l = new Label(composite, SWT.LEFT | SWT.WRAP);
167            l.setText("Type:");
168            gd = new GridData();
169            gd.horizontalAlignment = GridData.BEGINNING;
170            l.setLayoutData(gd);
171           
172            classType = new Combo(composite, SWT.READ_ONLY);
173            classType.setItems(new String [] {"model", "class", "connector", "record",
174                    "block", "type", "function"});
175            classType.setVisibleItemCount(7);
176            classType.select(0);           
177                   
178            gd = new GridData();
179            gd.horizontalAlignment = GridData.BEGINNING;
180            classType.setLayoutData(gd);
181           
182            classType.addSelectionListener(new SelectionListener()
183            {
184
185                public void widgetSelected(SelectionEvent e)
186                {
187                    initialEquation.setEnabled
188                    (NewClassWizard.classTypeHaveEquations(classType.getText()));                   
189                }
190
191                public void widgetDefaultSelected(SelectionEvent e)
192                {}
193               
194            });
195           
196           
197            /* fill upp 'empty' space */
198            new Label(composite, SWT.NONE);
199            new Label(composite, SWT.NONE);
200           
201            /* initial equation block */
202            initialEquation = new Button(composite, SWT.CHECK);
203            initialEquation.setText("include initial equation block");
204           
205            gd = new GridData();
206            gd.horizontalAlignment = GridData.BEGINNING;
207            initialEquation.setLayoutData(gd);
208
209        }
210
211        private void sourceFolderChanged()
212        {
213            IResource container = ResourcesPlugin.getWorkspace().getRoot()
214                    .findMember(new Path(sourceFolder.getText()));
215
216            sourceFolderValid = false;
217            if (sourceFolder.getText().length() == 0) {
218                updateStatus("File container must be specified", DialogPage.ERROR);
219                return;
220            }
221            if (container == null
222                    || (container.getType() & (IResource.PROJECT | IResource.FOLDER)) == 0) {
223                updateStatus("File container must exist", DialogPage.ERROR);
224                return;
225            }
226            if (!container.isAccessible()) {
227                updateStatus("Project must be writable", DialogPage.ERROR);
228                return;
229            }
230            sourceFolderValid = true;
231            updateStatus(null, DialogPage.NONE);
232        }
233
234        /**
235         * @return true if name is a valid modelica class name
236         */
237        protected boolean isLegalClassName(String name)
238        {
239            return classNamePattern.matcher(name).matches();
240        }
241       
242        public void init(IStructuredSelection selection)
243        {
244            if (selection == null || selection.size() != 1)
245            {
246                return;
247            }
248            if (!(selection.getFirstElement() instanceof IResource))
249            {
250                return;
251            }
252           
253            /*
254             * now we know that a single element of type IResource is selected
255             */
256            IResource sel = (IResource) selection.getFirstElement();
257
258            this.selection = sel.getFullPath();
259            if (sel.getType() == IResource.FILE)
260            {
261                this.selection = this.selection.removeLastSegments(1);
262            }
263        }
264       
265        private void handleBrowse()
266        {
267            ContainerSelectionDialog dialog =
268                new ContainerSelectionDialog(
269                    getShell(), ResourcesPlugin.getWorkspace().getRoot(), false,
270                    "Choose a source folder:");
271           
272            if (dialog.open() == ContainerSelectionDialog.OK)
273            {
274                Object[] result = dialog.getResult();
275                if (result.length == 1)
276                {
277                    setSourceFolder((IPath) result[0]);
278                }
279            }
280        }
281       
282        private void updateStatus(String message, int messageType)
283        {
284            setMessage(message, messageType);
285            setPageComplete((classNameValid && sourceFolderValid));
286        }
287
288
289        public void setSourceFolder(IPath path)
290        {
291            if (path != null)
292            {               
293                sourceFolder.setText(path.makeRelative().toString());
294                setPageComplete(isPageComplete());
295                sourceFolderValid = true;
296            }                       
297        }
298
299    }
300
301
302    private NewClassPage classPage = new NewClassPage();
303
304    public NewClassWizard()
305    {
306        super();
307    }
308
309    /**
310     * @param classType
311     * @return false if class type can't have equations, e.g.
312     * false is returned for record and connector
313     */
314    public static boolean classTypeHaveEquations(String classType)
315    {
316        return 
317        !(classType.equals("record") || classType.equals("connector"));
318    }
319   
320    @Override
321    public boolean performFinish()
322    {
323        final String sourceFolder = classPage.sourceFolder.getText();
324        final String className = classPage.className.getText();
325        final String classType = classPage.classType.getText();
326        final boolean initialEquationBlock = 
327            classPage.initialEquation.getSelection();
328       
329        IRunnableWithProgress op = new IRunnableWithProgress() {
330            public void run(IProgressMonitor monitor) 
331                                throws InvocationTargetException
332             {
333                try 
334                {
335                    doFinish(sourceFolder, className, classType, 
336                            initialEquationBlock, monitor);
337                } 
338                catch (CoreException e)
339                {
340                    throw new InvocationTargetException(e);
341                }
342                finally 
343                {
344                    monitor.done();
345                }
346            }
347        };
348        try {
349            getContainer().run(true, false, op);
350        } catch (InterruptedException e) {
351            return false;
352        } catch (InvocationTargetException e) {
353            Throwable realException = e.getTargetException();
354            MessageDialog.openError(getShell(), "Error", realException.getMessage());
355            return false;
356        }
357        return true;
358    }
359
360    protected void doFinish(String sourceFolder, String className, 
361            String classType, boolean initialEquationBlock, IProgressMonitor monitor)
362    throws CoreException
363    {
364        // create a sample file
365        monitor.beginTask("Creating " + className, 2);
366       
367        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
368        IResource resource = root.findMember(new Path(sourceFolder));
369       
370        IContainer container = (IContainer) resource;
371       
372        final IFile file = container.getFile(new Path(className+".mo"));
373       
374        boolean haveEquationBlock = 
375            classTypeHaveEquations(classType);
376       
377        String contents = 
378            classType + " " + className + "\n\n" +
379            ( haveEquationBlock ? "equation\n\n" : ""  ) + 
380            ( (haveEquationBlock && initialEquationBlock) 
381                    ? "initial equation\n\n" : "" ) +
382            "end " + className + ";";
383       
384        System.out.println(haveEquationBlock +" "+ initialEquationBlock);
385       
386        try {
387            InputStream stream = new ByteArrayInputStream(contents.getBytes());
388            if (file.exists()) {
389                file.appendContents(stream, true, true, monitor);
390            } else {
391                file.create(stream, true, monitor);
392            }
393            stream.close();
394        } catch (IOException e) {
395        }
396        monitor.worked(1);
397        monitor.setTaskName("Opening file for editing...");
398        getShell().getDisplay().asyncExec(new Runnable() {
399            public void run() {
400                IWorkbenchPage page =
401                    PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
402                try {
403                    IDE.openEditor(page, file, true);
404                } catch (PartInitException e) {
405                }
406            }
407        });
408        monitor.worked(1);
409
410    }
411
412    public void init(IWorkbench workbench, IStructuredSelection selection)
413    {
414        classPage.init(selection);
415        setWindowTitle("New Modelica Class");
416    }
417
418    @Override
419    public void addPages()
420    {
421        addPage(classPage);
422    }
423}
Note: See TracBrowser for help on using the repository browser.