2525import com .intellij .ide .actions .CreateFileFromTemplateDialog .Builder ;
2626import com .intellij .ide .fileTemplates .FileTemplate ;
2727import com .intellij .ide .fileTemplates .FileTemplateManager ;
28+ import com .intellij .ide .fileTemplates .FileTemplateUtil ;
29+ import com .intellij .openapi .module .Module ;
30+ import com .intellij .openapi .module .ModuleUtilCore ;
2831import com .intellij .openapi .project .DumbAware ;
2932import com .intellij .openapi .project .Project ;
33+ import com .intellij .openapi .projectRoots .Sdk ;
34+ import com .intellij .openapi .roots .ProjectRootManager ;
35+ import com .intellij .openapi .ui .InputValidator ;
36+ import com .intellij .openapi .util .io .FileUtilRt ;
37+ import com .intellij .openapi .util .text .StringUtil ;
3038import com .intellij .psi .PsiDirectory ;
39+ import com .intellij .psi .PsiElement ;
3140import com .intellij .psi .PsiFile ;
41+ import de .halirutan .mathematica .file .MathematicaFileType ;
42+ import de .halirutan .mathematica .file .MathematicaTemplateProperties ;
43+ import de .halirutan .mathematica .module .MathematicaLanguageLevelModuleExtension ;
44+ import de .halirutan .mathematica .sdk .MathematicaLanguageLevel ;
45+ import de .halirutan .mathematica .sdk .MathematicaSdkType ;
3246import de .halirutan .mathematica .util .MathematicaIcons ;
3347
34- import java .io . File ;
48+ import java .util . Properties ;
3549
3650/**
3751 * Provides the creation of new Mathematica files through the IDEA <em >new...</em> action.
52+ * <p>
53+ * TODO: This should be reworked.
54+ * The global string identifier for the templates should use {@link de.halirutan.mathematica.file.MathematicaFileTemplateProvider}
55+ * instead. Furthermore, we don't use the framework of {@link CreateFileFromTemplateAction} which is ugly as shit.
56+ * Instead, the variables we set inside the file template could be live templates that are active as soon as the file
57+ * is created and we only fill it with the default values. This gives the user the ability to fix settings. Not a pressing
58+ * matter so I'll leave it for now.
3859 *
3960 * @author patrick (4/8/13)
4061 */
4162public class CreateMathematicaFile extends CreateFileFromTemplateAction implements DumbAware {
4263 private static final String NEW_M_FILE = "New Mathematica file" ;
4364
65+ private static final String PACKAGE = "Package" ;
66+ private static final String PLAIN = "Plain" ;
67+ private static final String TEST = "Test" ;
68+ private static final String NOTEBOOK = "Notebook" ;
69+ private Project myProject = null ;
70+
4471 public CreateMathematicaFile () {
4572 super (NEW_M_FILE , "Creates a new .m Mathematica package file" , MathematicaIcons .FILE_ICON );
4673 }
4774
48- /**
49- * This is stolen from here {@link http://stackoverflow.com/a/990492/1078614}
50- *
51- * @param s
52- * filename with possible extension
53- * @return filename without extension
54- */
55- private static String removeExtension (String s ) {
56-
57- String separator = File .separator ;
58- String filename ;
59-
60- // Remove the path up to the filename.
61- int lastSeparatorIndex = s .lastIndexOf (separator );
62- if (lastSeparatorIndex == -1 ) {
63- filename = s ;
64- } else {
65- filename = s .substring (lastSeparatorIndex + 1 );
66- }
67-
68- // Remove the extension.
69- int extensionIndex = filename .lastIndexOf ("." );
70- if (extensionIndex == -1 )
71- return filename ;
72-
73- return filename .substring (0 , extensionIndex );
74- }
75-
7675 @ Override
7776 protected void buildDialog (Project project , PsiDirectory directory , Builder builder ) {
78- builder .setTitle (NEW_M_FILE ).addKind ("Package" , MathematicaIcons .FILE_ICON , "Package" );
79- builder .setTitle (NEW_M_FILE ).addKind ("Plain" , MathematicaIcons .FILE_ICON , "Plain" );
80- builder .setTitle (NEW_M_FILE ).addKind ("Test" , MathematicaIcons .FILE_ICON , "Test" );
81- builder .setTitle (NEW_M_FILE ).addKind ("Notebook" , MathematicaIcons .FILE_ICON , "Notebook" );
77+ myProject = project ;
78+ final MyNameValidator nameValidator = new MyNameValidator (MathematicaFileType .DEFAULT_EXTENSIONS );
79+ builder .setTitle (NEW_M_FILE ).addKind (PACKAGE , MathematicaIcons .FILE_ICON , PACKAGE );
80+ builder .setTitle (NEW_M_FILE ).addKind (PLAIN , MathematicaIcons .FILE_ICON , PLAIN );
81+ builder .setTitle (NEW_M_FILE ).addKind (TEST , MathematicaIcons .FILE_ICON , TEST );
82+ builder .setTitle (NEW_M_FILE ).addKind (NOTEBOOK , MathematicaIcons .FILE_ICON , NOTEBOOK );
83+ builder .setValidator (nameValidator );
8284 }
8385
8486 @ Override
@@ -98,9 +100,79 @@ public boolean equals(Object obj) {
98100
99101 @ Override
100102 protected PsiFile createFile (String name , String templateName , PsiDirectory dir ) {
101- final FileTemplate template = FileTemplateManager .getInstance (dir .getProject ()).getInternalTemplate (templateName );
102- String fileName = removeExtension (name );
103- return createFileFromTemplate (fileName , template , dir );
103+ MathematicaLanguageLevel version = null ;
104+ final String fileWithoutExtension = StringUtil .trimExtensions (name );
105+ final Module module = ModuleUtilCore .findModuleForFile (dir .getVirtualFile (), myProject );
106+ if (module != null ) {
107+ final MathematicaLanguageLevelModuleExtension languageLevelModuleExtension =
108+ MathematicaLanguageLevelModuleExtension .getInstance (module );
109+ if (languageLevelModuleExtension != null ) {
110+ version = languageLevelModuleExtension .getMathematicaLanguageLevel ();
111+ } else {
112+ final Sdk projectSdk = ProjectRootManager .getInstance (myProject ).getProjectSdk ();
113+ if (projectSdk instanceof MathematicaSdkType ) {
114+ version = MathematicaLanguageLevel .createFromSdk (projectSdk );
115+ }
116+ }
117+ }
118+ if (version == null ) {
119+ version = MathematicaLanguageLevel .HIGHEST ;
120+ }
121+
122+ MathematicaTemplateProperties props = MathematicaTemplateProperties .create ();
123+ props .setProperty (MathematicaTemplateProperties .MATHEMATICA_VERSION , version .getName ());
124+ props .setProperty (MathematicaTemplateProperties .CONTEXT , fileWithoutExtension + "`" );
125+ props .setProperty (MathematicaTemplateProperties .PACKAGE_NAME , fileWithoutExtension );
126+ props .setProperty (MathematicaTemplateProperties .PACKAGE_VERSION , "0.1" );
127+
128+ final FileTemplateManager fileTemplateManager = FileTemplateManager .getInstance (myProject );
129+ final Properties defaultProperties = fileTemplateManager .getDefaultProperties ();
130+ defaultProperties .putAll (props .getProperties ());
131+
132+ final FileTemplate template = fileTemplateManager .getInternalTemplate (templateName );
133+ try {
134+ final PsiElement psiElement = FileTemplateUtil .createFromTemplate (template , name , defaultProperties , dir );
135+ if (psiElement instanceof PsiFile ) {
136+ return (PsiFile ) psiElement ;
137+ }
138+ } catch (Exception e ) {
139+ LOG .error ("Error while creating new file" , e );
140+ }
141+ LOG .error ("Could not create file" );
142+ return null ;
104143 }
105144
145+ /**
146+ * Provides a simple check for file extension
147+ */
148+ private class MyNameValidator implements InputValidator {
149+
150+ private final String [] myExtensions ;
151+
152+ MyNameValidator (String [] myExtensions ) {
153+ this .myExtensions = myExtensions ;
154+ }
155+
156+ @ Override
157+ public boolean checkInput (String inputString ) {
158+ return inputString != null && hasValidFileExtension (inputString , myExtensions );
159+ }
160+
161+ private boolean hasValidFileExtension (String input , String ... extensions ) {
162+ if (FileUtilRt .getNameWithoutExtension (input ).equals (input )) {
163+ return true ;
164+ }
165+ for (String ext : extensions ) {
166+ if (FileUtilRt .extensionEquals (input , ext )) return true ;
167+ }
168+ return false ;
169+ }
170+
171+ @ Override
172+ public boolean canClose (String inputString ) {
173+ return checkInput (inputString );
174+ }
175+ }
176+
177+
106178}
0 commit comments