package com.rthoni.intellij.codefromds.ui.dialogs; import com.intellij.database.model.DasObject; import com.intellij.database.model.DasTable; import com.intellij.database.psi.DbDataSource; import com.intellij.database.psi.DbPsiFacade; import com.intellij.database.util.DasUtil; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.JBColor; import com.intellij.ui.components.JBList; import com.rthoni.intellij.codefromds.business.Helper; import com.rthoni.intellij.codefromds.dbo.ColumnSelection; import com.rthoni.intellij.codefromds.dbo.DataSourceSelection; import com.rthoni.intellij.codefromds.dbo.GenerateOptions; import com.rthoni.intellij.codefromds.dbo.TableSelection; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionListener; import java.awt.event.ActionListener; import java.io.File; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Vector; import java.util.function.Consumer; import java.util.stream.Collectors; /** * Created by robin on 11/14/16. */ public class GenerateDialog extends DialogWrapper { private JPanel _panel; private JBList _listDatasources; private JBList _listTables; private JBList _listColumns; private TextFieldWithBrowseButton _textModels; private TextFieldWithBrowseButton _textDataSOurceTemplate; private TextFieldWithBrowseButton _textModelsTemplate; private TextFieldWithBrowseButton _textConfigPath; private GenerateOptions _options; public GenerateDialog(@Nullable Project project) { super(project); setTitle("Code FROM data source"); setOptions(null); init(); } public GenerateOptions getOptions() { return _options; } public void setOptions(GenerateOptions options) { _options = options; if (_options != null) { showSource(_options.getSelection()); _textModels.setText(_options.getModelsPath()); _textDataSOurceTemplate.setText(_options.getDataSourceTemplatePath()); _textModelsTemplate.setText(_options.getModelsTemplatePath()); _textConfigPath.setText(_options.getConfigPath()); } else { showSource(null); _textModels.setText(""); _textDataSOurceTemplate.setText(""); _textModelsTemplate.setText(""); _textConfigPath.setText(""); } } @Nullable @Override protected ValidationInfo doValidate() { ValidationInfo info = null; File modelDir = _options == null ? null : new File(_options.getModelsPath()); File dataSourceTemplatePath = _options == null ? null : new File(_options.getDataSourceTemplatePath()); File modelsTemplatePath = _options == null ? null : new File(_options.getModelsTemplatePath()); File configPath = _options == null ? null : new File(_options.getConfigPath()); File configDir = _options == null ? null : new File(configPath.getParent()); if (_options == null) { info = new ValidationInfo("No Data Source Selected", _listDatasources); } else if (!modelDir.exists() || !modelDir.isDirectory()) { info = new ValidationInfo("Models folder does not exists", _textModels.getTextField()); } else if (!dataSourceTemplatePath.exists() || !dataSourceTemplatePath.isFile()) { info = new ValidationInfo("Data source template file does not exists", _textDataSOurceTemplate.getTextField()); } else if (!modelsTemplatePath.exists() || !modelsTemplatePath.isFile()) { info = new ValidationInfo("Models template file does not exists", _textModelsTemplate.getTextField()); } else if (!configDir.exists() || !configDir.isDirectory()) { info = new ValidationInfo("Configuration file parent folder does not exists", _textConfigPath.getTextField()); } return info; } @Nullable @Override protected JComponent createCenterPanel() { List dataSources = Helper.getDataSources(); _listDatasources.setListData(dataSources.stream().map(DasObject::getName).toArray(String[]::new)); _listDatasources.addListSelectionListener(e -> { if (!e.getValueIsAdjusting()) { int index = _listDatasources.getSelectedIndex(); if (index == -1) { setOptions(null); } else { setOptions(new GenerateOptions(dataSources.get(index))); } } }); _listTables.addListSelectionListener(e -> { if (!e.getValueIsAdjusting()) { int index = _listTables.getSelectedIndex(); if (index == -1) { showTable(null); } else { showTable(_options.getSelection().getTables().get(index)); } } }); setupTextField(_textModels, null, true); setupTextField(_textDataSOurceTemplate, null, false); setupTextField(_textModelsTemplate, null, false); setupTextField(_textConfigPath, null, false); setupTextFieldListener(_textModels.getTextField(), s -> _options.setModelsPath(s)); setupTextFieldListener(_textDataSOurceTemplate.getTextField(), s -> _options.setDataSourceTemplatePath(s)); setupTextFieldListener(_textModelsTemplate.getTextField(), s -> _options.setModelsTemplatePath(s)); setupTextFieldListener(_textConfigPath.getTextField(), s -> _options.setConfigPath(s)); _listTables.setCellRenderer(new ColoredListCellRenderer() { @Override protected void customizeCellRenderer(@NotNull JList jList, Object o, int i, boolean b, boolean b1) { TableSelection tableSelection = _options.getSelection().getTables().get(i); if (tableSelection.hasAll()) { setBackground(JBColor.GREEN); } else if (tableSelection.hasNone()) { setBackground(JBColor.RED); } else { setBackground(JBColor.ORANGE); } append(tableSelection.getTable().getName()); } }); if (dataSources.size() > 0) { _listDatasources.setSelectedIndices(new int[]{0}); } return _panel; } private void setupTextFieldListener(JTextField field, Consumer consumer) { field.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { changed(); } @Override public void removeUpdate(DocumentEvent e) { changed(); } @Override public void changedUpdate(DocumentEvent e) { changed(); } public void changed() { consumer.accept(field.getText()); } }); } private void setupTextField(TextFieldWithBrowseButton field, Project project, boolean dirsOnly) { for (ActionListener l : field.getButton().getActionListeners()) { field.getButton().removeActionListener(l); } field.addBrowseFolderListener("Choose Models Destination Folder", "Choose folder", project, dirsOnly ? FileChooserDescriptorFactory.createSingleFolderDescriptor() : FileChooserDescriptorFactory.createSingleFileDescriptor()); } private void showSource(DataSourceSelection source) { if (source != null) { List tables = source.getTables().stream().map(t -> t.getTable().getName()).collect(Collectors.toList()); _listTables.setListData(tables.toArray(new String[tables.size()])); if (tables.size() > 0) { showTable(source.getTables().get(0)); } else { showTable(null); } } else { _listTables.setListData(new String[]{}); showTable(null); } } private int[] getSelectedIndices(final TableSelection table) { List columns = table.getColumns(); List indices = new Vector<>(); for (int i = 0; i < columns.size(); ++i) { if (columns.get(i).isSelected()) { indices.add(i); } } return indices.stream().mapToInt(Integer::intValue).toArray(); } private void updateSelection(final TableSelection table) { List columns = table.getColumns(); for (int i = 0; i < columns.size(); ++i) { columns.get(i).setSelected(_listColumns.isSelectedIndex(i)); } } private void showTable(TableSelection table) { for (ListSelectionListener e : _listColumns.getListSelectionListeners()) { _listColumns.removeListSelectionListener(e); } if (table != null) { _listColumns.setListData(table.getColumns().stream().map(c -> c.getColumn().getName()).toArray(String[]::new)); int[] indices = getSelectedIndices(table); _listColumns.setSelectedIndices(indices); _listColumns.addListSelectionListener(e -> { if (!e.getValueIsAdjusting()) { _listTables.updateUI(); updateSelection(table); } }); } else { _listColumns.setListData(new String[]{}); } } }