package com.cedricziel.idea.typo3.generation.action; import com.cedricziel.idea.typo3.container.IconProvider; import com.cedricziel.idea.typo3.domain.TYPO3ExtensionDefinition; import com.cedricziel.idea.typo3.domain.TYPO3IconDefinition; import com.cedricziel.idea.typo3.util.ExtensionFileGenerationUtil; import com.cedricziel.idea.typo3.util.Slugify; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.HashMap; import java.util.Map; public class GenerateFscElementForm extends JDialog { private final Project project; private final TYPO3ExtensionDefinition extensionDefinition; private JTextField elementTitle; private JTextField elementName; private JTextArea elementDescription; private JComboBox icon; private JButton generateButton; private JButton cancelButton; private JPanel panel; private Slugify slugger; public GenerateFscElementForm(@NotNull Project project, TYPO3ExtensionDefinition extensionDefinition) { this.project = project; this.extensionDefinition = extensionDefinition; IconProvider iconProvider = IconProvider.getInstance(project); slugger = new Slugify().withUnderscoreSeparator(true); DefaultComboBoxModel model = new DefaultComboBoxModel(); for (TYPO3IconDefinition iconDefinition : iconProvider.all(project)) { model.addElement(iconDefinition.getIdentifier()); } this.icon.setModel(model); cancelButton.addActionListener(e -> onCancel()); generateButton.addActionListener(e -> onGenerate()); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); elementTitle.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent documentEvent) { onTitleChange(); } @Override public void removeUpdate(DocumentEvent documentEvent) { onTitleChange(); } @Override public void changedUpdate(DocumentEvent documentEvent) { onTitleChange(); } }); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { onCancel(); } }); } public static GenerateFscElementForm create(@NotNull Component c, @NotNull Project project, TYPO3ExtensionDefinition extensionDefinition) { GenerateFscElementForm frame = new GenerateFscElementForm(project, extensionDefinition); frame.setTitle("Generate Fluid Styled Content Element"); frame.setContentPane(frame.panel); frame.setModal(true); frame.setLocationRelativeTo(c); frame.pack(); frame.setVisible(true); return frame; } private void onTitleChange() { this.elementName.setText(slugger.slugify(elementTitle.getText())); } private void onGenerate() { ApplicationManager.getApplication().runWriteAction(new Thread(this::generate)); } private void onCancel() { dispose(); } /** * Does the actual code generation. */ private void generate() { String formElementName = this.elementName.getText(); String formElementTitle = this.elementTitle.getText(); String formElementDescription = this.elementDescription.getText(); String successMessage = "New Content Element \"" + formElementName + "\" in extension " + extensionDefinition.getExtensionKey() + " successfully created."; String errorMessageOverridesExist = "The TCA definition file for the element already exists. Unsupported operation."; // Exit if element exists. Maybe one day... *sigh* if (ExtensionFileGenerationUtil.extensionHasFile(extensionDefinition, "Configuration/TCA/Overrides/tt_content_element_" + formElementName + ".php")) { Notification notification = new Notification( "TYPO3 CMS Plugin", "TYPO3 CMS", errorMessageOverridesExist, NotificationType.ERROR ); Notifications.Bus.notify(notification, this.project); this.dispose(); return; } /* * Build template context. It will be available in the templates through '{{ marker }}' markers */ Map<String, String> context = new HashMap<>(); context.put("elementName", formElementName); context.put("elementTitle", formElementTitle); context.put("elementDescription", formElementDescription); context.put("extensionKey", extensionDefinition.getExtensionKey()); context.put("templateName", StringUtils.capitalize(formElementName) + ".html"); context.put("icon", (String) this.icon.getSelectedItem()); /* * Generate element main TypoScript */ PsiElement element = ExtensionFileGenerationUtil.fromTemplate( "contentElement/fsc/ts_setup.typoscript", "Configuration/TypoScript/ContentElement", formElementName + ".typoscript", extensionDefinition, context, project ); new OpenFileDescriptor(project, element.getContainingFile().getVirtualFile(), 0).navigate(true); /* * Generate element main fluid template */ PsiElement templateElement = ExtensionFileGenerationUtil.fromTemplate( "contentElement/fsc/element.html", "Resources/Private/Templates/ContentElements", context.get("templateName"), extensionDefinition, context, project ); new OpenFileDescriptor(project, templateElement.getContainingFile().getVirtualFile(), 0).navigate(true); /* * Generate element TypoScript include to main TS template */ String ceImport = "<INCLUDE_TYPOSCRIPT: source=\"FILE:EXT:" + extensionDefinition.getExtensionKey() + "/Configuration/TypoScript/ContentElement/" + formElementName + ".typoscript\">"; VirtualFile mainTsFile = ExtensionFileGenerationUtil.appendOrCreate( ceImport, "Configuration/TypoScript", "setup.txt", extensionDefinition, context, project ); if (mainTsFile == null) { return; } new OpenFileDescriptor(project, mainTsFile, 0).navigate(true); /* * Generate New content element wizard tsconfig */ String newCeTsconfig = ExtensionFileGenerationUtil.readTemplateToString("contentElement/fsc/newcewizard.tsconfig", context); VirtualFile newCeTsConfigFile = ExtensionFileGenerationUtil.appendOrCreate( newCeTsconfig, "Configuration/PageTSconfig", "NewContentElementWizard.tsconfig", extensionDefinition, context, project ); new OpenFileDescriptor(project, newCeTsConfigFile, 0).navigate(true); /* * Generate element TCA overrides */ PsiElement elementTcaOverrides = ExtensionFileGenerationUtil.fromTemplate( "contentElement/fsc/tca_overrides_ttcontent.php", "Configuration/TCA/Overrides", "tt_content_element_" + formElementName + ".php", extensionDefinition, context, project ); new OpenFileDescriptor(project, elementTcaOverrides.getContainingFile().getVirtualFile(), 0).navigate(true); if (!ExtensionFileGenerationUtil.extensionHasFile(extensionDefinition, "Configuration/TCA/Overrides/sys_template.php")) { /* * Generate static template imports */ PsiElement sysTemplateImport = ExtensionFileGenerationUtil.fromTemplate( "contentElement/fsc/tca_overrides_systemplate.php", "Configuration/TCA/Overrides", "sys_template.php", extensionDefinition, context, project ); new OpenFileDescriptor(project, sysTemplateImport.getContainingFile().getVirtualFile(), 0).navigate(true); } else { successMessage += "\nsys_template overrides already exist. Please check that the static template is added."; } Notification notification = new Notification( "TYPO3 CMS Plugin", "TYPO3 CMS", successMessage, NotificationType.INFORMATION ); Notifications.Bus.notify(notification, this.project); this.dispose(); } }