You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2018/11/22 13:59:49 UTC

[2/4] cayenne git commit: Add dbImport on dataDomain tab

Add dbImport on dataDomain tab


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/5a0b4a76
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/5a0b4a76
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/5a0b4a76

Branch: refs/heads/master
Commit: 5a0b4a76b8232a8e85f8505c0ceb64fa11f9ea6c
Parents: 2ee1782
Author: Arseni Bulatski <an...@gmail.com>
Authored: Wed Nov 21 17:35:23 2018 +0300
Committer: Arseni Bulatski <an...@gmail.com>
Committed: Wed Nov 21 17:49:11 2018 +0300

----------------------------------------------------------------------
 .../configuration/xml/DataChannelMetaData.java  |   9 ++
 .../xml/DefaultDataChannelMetaData.java         |  25 +++-
 .../xml/NoopDataChannelMetaData.java            |   5 +
 .../modeler/CayenneModelerController.java       |  12 +-
 .../cayenne/modeler/ProjectController.java      |  18 +--
 .../apache/cayenne/modeler/ProjectTreeView.java |   4 +-
 .../action/ReverseEngineeringAction.java        |  55 ++++----
 .../dialog/db/load/DbLoadResultDialog.java      | 101 +++++++++-----
 .../dialog/db/load/ModelerDbImportAction.java   |  49 +++++--
 .../cayenne/modeler/editor/AdditionalTab.java   |  71 ----------
 .../modeler/editor/AdditionalTabController.java | 100 --------------
 .../modeler/editor/DataDomainTabbedView.java    |  18 ++-
 .../modeler/editor/DataMapTabbedView.java       |   9 +-
 .../cayenne/modeler/editor/GeneratorsPanel.java | 102 ++++++++++++++
 .../cayenne/modeler/editor/GeneratorsTab.java   |  98 +++++++++++++
 .../modeler/editor/GeneratorsTabController.java | 138 +++++++++++++++++++
 .../editor/GlobalDbImportController.java        |  77 +++++++++++
 .../apache/cayenne/modeler/editor/TabPanel.java |  59 --------
 .../modeler/editor/cgen/domain/CgenTab.java     |  14 +-
 .../editor/cgen/domain/CgenTabController.java   |  16 ++-
 .../modeler/editor/dbimport/DbImportView.java   |  25 ++--
 .../editor/dbimport/TreeToolbarPanel.java       |   6 +-
 .../editor/dbimport/domain/DbImportTab.java     |  34 +++++
 .../dbimport/domain/DbImportTabController.java  |  78 +++++++++++
 24 files changed, 765 insertions(+), 358 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelMetaData.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelMetaData.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelMetaData.java
index 3e0cd20..a54219b 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelMetaData.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DataChannelMetaData.java
@@ -61,4 +61,13 @@ public interface DataChannelMetaData {
      * @return value or {@code null} if no data available
      */
     <T> T get(ConfigurationNode key, Class<T> type);
+
+    /**
+     * @since 4.1
+     * @param key object for wich we want meta data
+     * @param type meta data type class
+     * @param <T> meta data type
+     * @return value or {@code null} if no can't remove
+     */
+    <T> T remove(ConfigurationNode key, Class<T> type);
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DefaultDataChannelMetaData.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DefaultDataChannelMetaData.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DefaultDataChannelMetaData.java
index 869abed..26be7db 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DefaultDataChannelMetaData.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/DefaultDataChannelMetaData.java
@@ -19,11 +19,11 @@
 
 package org.apache.cayenne.configuration.xml;
 
+import org.apache.cayenne.configuration.ConfigurationNode;
+
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.cayenne.configuration.ConfigurationNode;
-
 /**
  * <p>
  *     Default implementation of {@link DataChannelMetaData} that stores data in Map.
@@ -88,4 +88,25 @@ public class DefaultDataChannelMetaData implements DataChannelMetaData {
 
         return type.cast(data.get(type));
     }
+
+    /**
+     *
+     * @param key object for wich we want meta data
+     * @param type meta data type class
+     * @param <T> data type
+     * @return removed value or {@code null}
+     */
+    @Override
+    public <T> T remove(ConfigurationNode key, Class<T> type) {
+        if(key == null || type == null) {
+            return null;
+        }
+
+        Map<Class<?>, Object> data = map.get(key);
+        if(data == null) {
+            return null;
+        }
+
+        return type.cast(data.remove(type));
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/NoopDataChannelMetaData.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/NoopDataChannelMetaData.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/NoopDataChannelMetaData.java
index cbcb696..3cc32b1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/NoopDataChannelMetaData.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/xml/NoopDataChannelMetaData.java
@@ -39,4 +39,9 @@ public class NoopDataChannelMetaData implements DataChannelMetaData {
         return null;
     }
 
+    @Override
+    public <T> T remove(ConfigurationNode key, Class<T> type) {
+        return null;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java
index 98f0bd4..3d3e93c 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java
@@ -23,6 +23,7 @@ import org.apache.cayenne.modeler.action.ExitAction;
 import org.apache.cayenne.modeler.action.OpenProjectAction;
 import org.apache.cayenne.modeler.dialog.validator.ValidatorDialog;
 import org.apache.cayenne.modeler.editor.EditorView;
+import org.apache.cayenne.modeler.editor.GlobalDbImportController;
 import org.apache.cayenne.modeler.init.platform.PlatformInitializer;
 import org.apache.cayenne.modeler.pref.ComponentGeometry;
 import org.apache.cayenne.modeler.pref.FSPath;
@@ -34,9 +35,9 @@ import org.apache.cayenne.project.validation.ProjectValidator;
 import org.apache.cayenne.validation.ValidationFailure;
 import org.apache.cayenne.validation.ValidationResult;
 
-import javax.swing.WindowConstants;
+import javax.swing.*;
 import javax.swing.filechooser.FileFilter;
-import java.awt.Component;
+import java.awt.*;
 import java.awt.datatransfer.DataFlavor;
 import java.awt.datatransfer.Transferable;
 import java.awt.dnd.DropTarget;
@@ -64,6 +65,8 @@ public class CayenneModelerController extends CayenneController {
     protected CayenneModelerFrame frame;
 	private EditorView editorView;
 
+	private GlobalDbImportController globalDbImportController;
+
     public CayenneModelerController(){}
 
     public CayenneModelerController(Application application) {
@@ -72,6 +75,7 @@ public class CayenneModelerController extends CayenneController {
         this.frame = new CayenneModelerFrame(application.getActionManager());
         application.getInjector().getInstance(PlatformInitializer.class).setupMenus(frame);
         this.projectController = new ProjectController(this);
+        this.globalDbImportController = new GlobalDbImportController();
     }
 
     @Override
@@ -297,6 +301,10 @@ public class CayenneModelerController extends CayenneController {
         }
     }
 
+    public GlobalDbImportController getGlobalDbImportController() {
+        return globalDbImportController;
+    }
+
     class ExpireThread extends Thread {
 
         int seconds;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectController.java
index 4c3e436..3dc2b3a 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectController.java
@@ -47,6 +47,7 @@ import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.ObjRelationship;
 import org.apache.cayenne.map.Procedure;
 import org.apache.cayenne.map.ProcedureParameter;
+import org.apache.cayenne.map.QueryDescriptor;
 import org.apache.cayenne.map.event.AttributeEvent;
 import org.apache.cayenne.map.event.DbAttributeListener;
 import org.apache.cayenne.map.event.DbEntityListener;
@@ -112,21 +113,12 @@ import org.apache.cayenne.modeler.util.CircularArray;
 import org.apache.cayenne.modeler.util.Comparators;
 import org.apache.cayenne.project.ConfigurationNodeParentGetter;
 import org.apache.cayenne.project.Project;
-import org.apache.cayenne.map.QueryDescriptor;
 import org.apache.cayenne.util.IDUtil;
 
 import javax.swing.event.EventListenerList;
-import java.awt.Component;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EventListener;
-import java.util.EventObject;
-import java.util.HashSet;
-import java.util.Iterator;
+import java.awt.*;
+import java.util.*;
 import java.util.List;
-import java.util.Set;
 import java.util.prefs.Preferences;
 
 /**
@@ -264,6 +256,10 @@ public class ProjectController extends CayenneController {
         return parent.getView();
     }
 
+    public void setCurrentDataMap(DataMap dataMap) {
+        currentState.map = dataMap;
+    }
+
     public Project getProject() {
         return project;
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeView.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeView.java
index 90ceb58..c2434f4 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeView.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeView.java
@@ -642,7 +642,9 @@ public class ProjectTreeView extends JTree implements DomainDisplayListener,
 
         positionNode(domainNode, newMapNode, Comparators
                 .getDataDomainChildrenComparator());
-        showNode(newMapNode);
+        if(!Application.getInstance().getFrameController().getGlobalDbImportController().isGlobalImport()) {
+            showNode(newMapNode);
+        }
     }
 
     public void dataMapRemoved(DataMapEvent e) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ReverseEngineeringAction.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ReverseEngineeringAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ReverseEngineeringAction.java
index 89b61db..63e2ffb 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ReverseEngineeringAction.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ReverseEngineeringAction.java
@@ -22,23 +22,20 @@ package org.apache.cayenne.modeler.action;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.dialog.db.DataSourceWizard;
 import org.apache.cayenne.modeler.dialog.db.DbActionOptionsDialog;
+import org.apache.cayenne.modeler.dialog.db.load.DbLoadResultDialog;
 import org.apache.cayenne.modeler.dialog.db.load.DbLoaderContext;
 import org.apache.cayenne.modeler.dialog.db.load.LoadDataMapTask;
+import org.apache.cayenne.modeler.editor.GlobalDbImportController;
 import org.apache.cayenne.modeler.editor.dbimport.DbImportView;
 import org.apache.cayenne.modeler.pref.DBConnectionInfo;
 import org.apache.cayenne.modeler.pref.DataMapDefaults;
 
+import javax.swing.*;
 import java.awt.event.ActionEvent;
 import java.sql.SQLException;
 import java.util.Collection;
-import javax.swing.SwingUtilities;
-import javax.swing.JOptionPane;
 
-import static org.apache.cayenne.modeler.pref.DBConnectionInfo.DB_ADAPTER_PROPERTY;
-import static org.apache.cayenne.modeler.pref.DBConnectionInfo.URL_PROPERTY;
-import static org.apache.cayenne.modeler.pref.DBConnectionInfo.USER_NAME_PROPERTY;
-import static org.apache.cayenne.modeler.pref.DBConnectionInfo.PASSWORD_PROPERTY;
-import static org.apache.cayenne.modeler.pref.DBConnectionInfo.JDBC_DRIVER_PROPERTY;
+import static org.apache.cayenne.modeler.pref.DBConnectionInfo.*;
 
 /**
  * Action that imports database structure into a DataMap.
@@ -63,11 +60,7 @@ public class ReverseEngineeringAction extends DBWizardAction<DbActionOptionsDial
         return ACTION_NAME;
     }
 
-    /**
-     * Connects to DB and delegates processing to DbLoaderController, starting it asynchronously.
-     */
-    @Override
-    public void performAction(ActionEvent event) {
+    public void performAction() {
         final DbLoaderContext context = new DbLoaderContext(application.getMetaData());
         DBConnectionInfo connectionInfo;
         if (!datamapPreferencesExist()) {
@@ -91,6 +84,13 @@ public class ReverseEngineeringAction extends DBWizardAction<DbActionOptionsDial
                     JOptionPane.ERROR_MESSAGE);
             return;
         }
+
+        GlobalDbImportController dbImportController = Application.getInstance().getFrameController().getGlobalDbImportController();
+        DbLoadResultDialog dbLoadResultDialog = dbImportController.createDialog();
+        if(!dbLoadResultDialog.isVisible()) {
+            dbImportController.showDialog();
+        }
+
         if(!context.buildConfig(connectionInfo, view)) {
             try {
                 context.getConnection().close();
@@ -98,17 +98,22 @@ public class ReverseEngineeringAction extends DBWizardAction<DbActionOptionsDial
             return;
         }
 
-        runLoaderInThread(context, new Runnable() {
-            @Override
-            public void run() {
-                application.getUndoManager().discardAllEdits();
-                try {
-                    context.getConnection().close();
-                } catch (SQLException ignored) {}
-            }
+        runLoaderInThread(context, () -> {
+            application.getUndoManager().discardAllEdits();
+            try {
+                context.getConnection().close();
+            } catch (SQLException ignored) {}
         });
     }
 
+    /**
+     * Connects to DB and delegates processing to DbLoaderController, starting it asynchronously.
+     */
+    @Override
+    public void performAction(ActionEvent event) {
+        performAction();
+    }
+
     private DBConnectionInfo getConnectionInfoFromPreferences() {
         DBConnectionInfo connectionInfo = new DBConnectionInfo();
         DataMapDefaults dataMapDefaults = getProjectController().
@@ -138,12 +143,10 @@ public class ReverseEngineeringAction extends DBWizardAction<DbActionOptionsDial
     }
 
     private void runLoaderInThread(final DbLoaderContext context, final Runnable callback) {
-        Thread th = new Thread(new Runnable() {
-            public void run() {
-                LoadDataMapTask task = new LoadDataMapTask(Application.getFrame(), "Reengineering DB", context);
-                task.startAndWait();
-                SwingUtilities.invokeLater(callback);
-            }
+        Thread th = new Thread(() -> {
+            LoadDataMapTask task = new LoadDataMapTask(Application.getFrame(), "Reengineering DB", context);
+            task.startAndWait();
+            SwingUtilities.invokeLater(callback);
         });
         th.start();
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoadResultDialog.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoadResultDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoadResultDialog.java
index 007a2e6..4b0c28b 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoadResultDialog.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoadResultDialog.java
@@ -21,15 +21,14 @@ package org.apache.cayenne.modeler.dialog.db.load;
 
 import com.jgoodies.forms.builder.DefaultFormBuilder;
 import com.jgoodies.forms.layout.FormLayout;
+import org.apache.cayenne.map.DataMap;
 
-import javax.swing.JButton;
-import javax.swing.JDialog;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTable;
-import javax.swing.ListSelectionModel;
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
 import javax.swing.table.DefaultTableModel;
-import java.awt.FlowLayout;
+import java.awt.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 /**
  * @since 4.1
@@ -39,15 +38,26 @@ public class DbLoadResultDialog extends JDialog {
     private static final int TABLE_ROW_HIGH = 24;
     private static final int TABLE_ROW_MARGIN = 3;
 
-    private DefaultTableModel tableModel;
-    private JTable table;
     private JButton okButton;
     private JButton revertButton;
     private String title;
 
-    DbLoadResultDialog(String title) {
+    private DefaultFormBuilder builder;
+
+    private ConcurrentMap<DataMap, JTable> tableForMap;
+    private JPanel tablePanel;
+    private JPanel buttonPanel;
+    private JScrollPane scrollPane;
+
+    public DbLoadResultDialog(String title) {
         super();
         this.title = title;
+        this.tableForMap = new ConcurrentHashMap<>();
+        this.tablePanel = new JPanel();
+        this.tablePanel.setLayout(new BoxLayout(this.tablePanel, BoxLayout.Y_AXIS));
+        this.scrollPane = new JScrollPane(tablePanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+        this.buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
         initElements();
         buildElements();
         configureDialog();
@@ -56,48 +66,61 @@ public class DbLoadResultDialog extends JDialog {
     private void configureDialog() {
         this.setResizable(false);
         this.setTitle(title);
-        this.pack();
         this.setLocationRelativeTo(null);
         this.setModal(false);
         this.setAlwaysOnTop(true);
+        this.setPreferredSize(new Dimension(400, 400));
+        this.scrollPane.setPreferredSize(new Dimension(400, 330));
+        this.pack();
     }
 
     private void initElements() {
-        tableModel = new DefaultTableModel() {
-            @Override
-            public boolean isCellEditable(int row, int col) {
-                return false;
-            }
-        };
-        table = new JTable(tableModel);
-        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-        table.setRowHeight(TABLE_ROW_HIGH);
-        table.setRowMargin(TABLE_ROW_MARGIN);
-        tableModel.addColumn("");
         revertButton = new JButton("Revert");
         okButton = new JButton("OK");
     }
 
-    private void buildElements() {
+    public void buildElements() {
         getRootPane().setDefaultButton(okButton);
-
         FormLayout layout = new FormLayout("fill:200dlu");
-        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
-        builder.append(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
-                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
-        JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
-        panel.add(revertButton);
-        panel.add(okButton);
-        builder.append(panel);
+        builder = new DefaultFormBuilder(layout);
+        builder.append(scrollPane);
+        buttonPanel.add(revertButton);
+        buttonPanel.add(okButton);
+        builder.append(buttonPanel);
         this.add(builder.getPanel());
     }
 
-    public void addRowToOutput(String output) {
-        tableModel.addRow(new Object[]{output});
+    private DefaultTableModel prepareTable(DataMap dataMap) {
+        if(tableForMap.containsKey(dataMap)) {
+            return (DefaultTableModel)tableForMap.get(dataMap).getModel();
+        }
+        DefaultTableModel tokensTableModel = new DefaultTableModel() {
+            @Override
+            public boolean isCellEditable(int row, int col) {
+                return false;
+            }
+        };
+        JPanel tablePane = new JPanel(new BorderLayout());
+        JLabel dataMapLabel = new JLabel(String.format("    %-20s", dataMap.getName()));
+        dataMapLabel.setBorder(new EmptyBorder(5,0,5,0));
+        tablePane.add(dataMapLabel, BorderLayout.NORTH);
+        JTable tokensTable = new JTable(tokensTableModel);
+        tokensTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        tokensTable.setRowHeight(TABLE_ROW_HIGH);
+        tokensTable.setRowMargin(TABLE_ROW_MARGIN);
+        tokensTableModel.addColumn("");
+        tablePane.add(tokensTable, BorderLayout.CENTER);
+        tableForMap.put(dataMap, tokensTable);
+        tablePanel.add(tablePane);
+        return tokensTableModel;
+    }
+
+    public synchronized void addRowToOutput(String output, DataMap dataMap) {
+        prepareTable(dataMap).addRow(new Object[]{output});
     }
 
-    public int getTableRowCount() {
-        return tableModel.getRowCount();
+    public synchronized void addMsg(DataMap dataMap) {
+        prepareTable(dataMap).addRow(new Object[]{String.format("    %-20s", "No changes to import")});
     }
 
     public JButton getOkButton() {
@@ -107,4 +130,12 @@ public class DbLoadResultDialog extends JDialog {
     public JButton getRevertButton() {
         return revertButton;
     }
+
+    public ConcurrentMap<DataMap, JTable> getTableForMap() {
+        return tableForMap;
+    }
+
+    public JPanel getTablePanel() {
+        return tablePanel;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
index e0f01e3..f17a707 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
@@ -28,16 +28,18 @@ import org.apache.cayenne.configuration.server.DbAdapterFactory;
 import org.apache.cayenne.configuration.xml.DataChannelMetaData;
 import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactoryProvider;
 import org.apache.cayenne.dbsync.merge.token.MergerToken;
+import org.apache.cayenne.dbsync.reverse.dbimport.DbImportConfiguration;
+import org.apache.cayenne.dbsync.reverse.dbimport.DefaultDbImportAction;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.editor.GlobalDbImportController;
 import org.apache.cayenne.project.ProjectSaver;
-import org.apache.cayenne.dbsync.reverse.dbimport.DbImportConfiguration;
-import org.apache.cayenne.dbsync.reverse.dbimport.DefaultDbImportAction;
 import org.slf4j.Logger;
 
-import javax.swing.JDialog;
-import javax.swing.JOptionPane;
+import javax.swing.*;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.List;
@@ -55,6 +57,8 @@ public class ModelerDbImportAction extends DefaultDbImportAction {
     private DbLoadResultDialog resultDialog;
     private boolean isNothingChanged;
 
+    private GlobalDbImportController globalDbImportController;
+
     public ModelerDbImportAction(@Inject Logger logger,
                                  @Inject ProjectSaver projectSaver,
                                  @Inject DataSourceFactory dataSourceFactory,
@@ -64,6 +68,7 @@ public class ModelerDbImportAction extends DefaultDbImportAction {
                                  @Inject DataChannelMetaData metaData,
                                  @Inject DataChannelDescriptorLoader dataChannelDescriptorLoader) {
         super(logger, projectSaver, dataSourceFactory, adapterFactory, mapLoader, mergerTokenFactoryProvider, dataChannelDescriptorLoader, metaData);
+        globalDbImportController = Application.getInstance().getFrameController().getGlobalDbImportController();
     }
 
     @Override
@@ -80,10 +85,11 @@ public class ModelerDbImportAction extends DefaultDbImportAction {
 
     @Override
     protected Collection<MergerToken> log(List<MergerToken> tokens) {
-        resultDialog = new DbLoadResultDialog(DIALOG_TITLE);
+        resultDialog = globalDbImportController.createDialog();
         logger.info("");
         if (tokens.isEmpty()) {
             logger.info("Detected changes: No changes to import.");
+            resultDialog.addMsg(targetMap);
             isNothingChanged = true;
             return tokens;
         }
@@ -92,7 +98,7 @@ public class ModelerDbImportAction extends DefaultDbImportAction {
         for (MergerToken token : tokens) {
             String logString = String.format("    %-20s %s", token.getTokenName(), token.getTokenValue());
             logger.info(logString);
-            resultDialog.addRowToOutput(logString);
+            resultDialog.addRowToOutput(logString, targetMap);
             isNothingChanged = false;
         }
 
@@ -100,23 +106,44 @@ public class ModelerDbImportAction extends DefaultDbImportAction {
         resultDialog.getOkButton().addActionListener(e -> {
             try {
                 commit();
+                checkForUnusedImports();
             } catch (Exception ex) {
                 throw new CayenneRuntimeException("Nothing to commit.");
-            } finally {
-                resultDialog.setVisible(false);
             }
         });
 
-        resultDialog.getRevertButton().addActionListener(e -> resultDialog.setVisible(false));
-        resultDialog.setVisible(true);
+        resultDialog.getRevertButton().addActionListener(e -> {
+            resetDialog();
+        });
+
+        resultDialog.addComponentListener(new ComponentAdapter() {
+            @Override
+            public void componentHidden(ComponentEvent e) {
+                resetDialog();
+            }
+        });
+
         return tokens;
     }
 
+    private void resetDialog() {
+        resultDialog.setVisible(false);
+        globalDbImportController.resetDialog();
+    }
+
+    private void checkForUnusedImports() {
+        globalDbImportController.checkImport(targetMap);
+        if(globalDbImportController.createDialog().getTableForMap().isEmpty()) {
+            resetDialog();
+            globalDbImportController.setGlobalImport(false);
+        }
+    }
+
     @Override
     protected void addMessageToLogs(String message, List<String> messages) {
         String formattedMessage = String.format("    %-20s", message);
         messages.add(formattedMessage);
-        resultDialog.addRowToOutput(formattedMessage);
+        resultDialog.addRowToOutput(formattedMessage, targetMap);
         isNothingChanged = false;
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AdditionalTab.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AdditionalTab.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AdditionalTab.java
deleted file mode 100644
index 3e5bafa..0000000
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AdditionalTab.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.apache.cayenne.modeler.editor;
-
-import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.modeler.util.ModelerUtil;
-
-import javax.swing.*;
-import java.awt.*;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentMap;
-
-public class AdditionalTab extends JPanel {
-
-    protected ProjectController projectController;
-    private AdditionalTabController additionalTabController;
-
-    private JCheckBox selectAll;
-    private JButton generateAll;
-
-    public AdditionalTab(ProjectController projectController, AdditionalTabController additionalTabController, String icon) {
-        this.projectController = projectController;
-        this.additionalTabController = additionalTabController;
-        this.selectAll = new JCheckBox();
-        generateAll = new JButton("Run");
-        generateAll.setEnabled(false);
-        generateAll.setIcon(ModelerUtil.buildIcon(icon));
-        generateAll.setPreferredSize(new Dimension(120, 30));
-        generateAll.addActionListener(action -> additionalTabController.runGenerators(additionalTabController.getSelectedDataMaps()));
-        setLayout(new BorderLayout());
-    }
-
-    public void initView() {
-        removeAll();
-        additionalTabController.createPanels();
-        FormLayout layout = new FormLayout(
-                "left:pref, 4dlu, 50dlu", "");
-        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
-        builder.setDefaultDialogBorder();
-        ConcurrentMap<DataMap, TabPanel> panels = additionalTabController.getGeneratorsPanels();
-
-        if(panels.isEmpty()) {
-            this.add(new JLabel("There are no configs."), BorderLayout.NORTH);
-            return;
-        }
-
-        JPanel selectAllPanel = new JPanel(new FlowLayout());
-        selectAllPanel.add(new JLabel("Select All"), FlowLayout.LEFT);
-        selectAllPanel.add(selectAll, FlowLayout.CENTER);
-        builder.append(selectAllPanel);
-        builder.nextLine();
-
-        SortedSet<DataMap> keys = new TreeSet<>(panels.keySet());
-        for(DataMap dataMap : keys) {
-            builder.append(panels.get(dataMap));
-            builder.nextLine();
-        }
-        builder.append(generateAll);
-        this.add(builder.getPanel(), BorderLayout.CENTER);
-    }
-
-    public JCheckBox getSelectAll() {
-        return selectAll;
-    }
-
-    public JButton getGenerateAll() {
-        return generateAll;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AdditionalTabController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AdditionalTabController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AdditionalTabController.java
deleted file mode 100644
index 80d08ad..0000000
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AdditionalTabController.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package org.apache.cayenne.modeler.editor;
-
-import org.apache.cayenne.configuration.DataChannelDescriptor;
-import org.apache.cayenne.gen.CgenConfiguration;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.modeler.dialog.ErrorDebugDialog;
-import org.apache.cayenne.project.Project;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.awt.event.ItemEvent;
-import java.util.Collection;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-
-public abstract class AdditionalTabController {
-
-    public static Logger logObj = LoggerFactory.getLogger(ErrorDebugDialog.class);
-    public ProjectController projectController;
-    public AdditionalTab view;
-
-    public ConcurrentMap<DataMap, TabPanel> generatorsPanels;
-    public Set<DataMap> selectedDataMaps;
-
-    public String icon;
-
-    public abstract void runGenerators(Set<DataMap> dataMap);
-
-    public void createPanels(){
-        Collection<DataMap> dataMaps = getDataMaps();
-        generatorsPanels.clear();
-        for(DataMap dataMap : dataMaps) {
-            TabPanel cgenPanel = new TabPanel(dataMap, "icon-datamap.png");
-            initListenersForPanel(cgenPanel);
-            generatorsPanels.put(dataMap, cgenPanel);
-        }
-        selectedDataMaps.forEach(dataMap -> {
-            if(generatorsPanels.get(dataMap) != null) {
-                TabPanel currPanel = generatorsPanels.get(dataMap);
-                currPanel.getCheckConfig().setSelected(true);
-            }
-        });
-    }
-
-    private void initListenersForPanel(TabPanel cgenPanel) {
-        cgenPanel.getCheckConfig().addItemListener(e -> {
-            if(e.getStateChange() == ItemEvent.SELECTED) {
-                selectedDataMaps.add(cgenPanel.getDataMap());
-            } else if(e.getStateChange() == ItemEvent.DESELECTED) {
-                selectedDataMaps.remove(cgenPanel.getDataMap());
-            }
-            setGenerateButtonDisabled();
-        });
-
-        cgenPanel.getToConfigButton().addActionListener(action -> showConfig(cgenPanel.getDataMap()));
-
-        view.getSelectAll().addItemListener(e -> {
-            if(e.getStateChange() == ItemEvent.SELECTED) {
-                getGeneratorsPanels().forEach((key, value) -> value.getCheckConfig().setSelected(true));
-            } else if(e.getStateChange() == ItemEvent.DESELECTED) {
-                getGeneratorsPanels().forEach((key, value) -> value.getCheckConfig().setSelected(false));
-            }
-            setGenerateButtonDisabled();
-        });
-    }
-
-    public abstract void showConfig(DataMap dataMap);
-
-    private void setGenerateButtonDisabled() {
-        if(selectedDataMaps.size() == 0) {
-            view.getGenerateAll().setEnabled(false);
-        } else {
-            view.getGenerateAll().setEnabled(true);
-        }
-    }
-
-    private Collection<DataMap> getDataMaps() {
-        Project project = projectController.getProject();
-        return  ((DataChannelDescriptor) project.getRootNode()).getDataMaps();
-    }
-
-    public AdditionalTab getView() {
-        return view;
-    }
-
-    public abstract CgenConfiguration createConfiguration(DataMap dataMap);
-
-    public ProjectController getProjectController() {
-        return projectController;
-    }
-
-    ConcurrentMap<DataMap, TabPanel> getGeneratorsPanels() {
-        return generatorsPanels;
-    }
-
-    Set<DataMap> getSelectedDataMaps() {
-        return selectedDataMaps;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainTabbedView.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainTabbedView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainTabbedView.java
index de4059e..20741af 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainTabbedView.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainTabbedView.java
@@ -21,6 +21,7 @@ package org.apache.cayenne.modeler.editor;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.action.GenerateCodeAction;
 import org.apache.cayenne.modeler.editor.cgen.domain.CgenTabController;
+import org.apache.cayenne.modeler.editor.dbimport.domain.DbImportTabController;
 import org.apache.cayenne.modeler.event.DomainDisplayEvent;
 import org.apache.cayenne.modeler.event.DomainDisplayListener;
 import org.apache.cayenne.modeler.event.EntityDisplayEvent;
@@ -41,6 +42,8 @@ public class DataDomainTabbedView extends JTabbedPane
     DataDomainGraphTab graphTab;
     private JScrollPane cgenView;
     private CgenTabController cgenTabController;
+    private JScrollPane dbImportView;
+    private DbImportTabController dbImportTabController;
 
     /**
      * constructor
@@ -65,15 +68,19 @@ public class DataDomainTabbedView extends JTabbedPane
         JScrollPane domainView = new JScrollPane(new DataDomainView(mediator));
         addTab("Main", domainView);
 
-        graphTab = new DataDomainGraphTab(mediator);
-        addTab("Graph", graphTab);
-
         addChangeListener(this);
         mediator.addDomainDisplayListener(this);
 
+        dbImportTabController = new DbImportTabController(mediator);
+        dbImportView = new JScrollPane(dbImportTabController.getView());
+        addTab("Db Import", dbImportView);
+
         cgenTabController = new CgenTabController(mediator);
         cgenView = new JScrollPane(cgenTabController.getView());
         addTab("Class Generation", cgenView);
+
+        graphTab = new DataDomainGraphTab(mediator);
+        addTab("Graph", graphTab);
     }
 
     public void stateChanged(ChangeEvent e) {
@@ -81,6 +88,8 @@ public class DataDomainTabbedView extends JTabbedPane
             graphTab.refresh();
         } else if(getSelectedComponent() == cgenView) {
             cgenTabController.getView().initView();
+        } else if(getSelectedComponent() == dbImportView) {
+            dbImportTabController.getView().initView();
         }
     }
 
@@ -95,5 +104,8 @@ public class DataDomainTabbedView extends JTabbedPane
         if(e.getSource() instanceof GenerateCodeAction) {
             setSelectedComponent(cgenView);
         }
+        if(getSelectedComponent() == dbImportView) {
+            fireStateChanged();
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java
index 9297481..a2f7814 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java
@@ -23,6 +23,7 @@ import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.editor.cgen.CodeGeneratorController;
 import org.apache.cayenne.modeler.editor.cgen.domain.CgenTab;
 import org.apache.cayenne.modeler.editor.dbimport.DbImportView;
+import org.apache.cayenne.modeler.editor.dbimport.domain.DbImportTab;
 
 import javax.swing.JScrollPane;
 import javax.swing.JTabbedPane;
@@ -76,10 +77,12 @@ public class DataMapTabbedView extends JTabbedPane{
             }
         });
         mediator.addDataMapDisplayListener(e -> {
-            if(isCgenTabActive() || isDbImportTabActive()) {
-                fireStateChanged();
-            } else if(e.getSource() instanceof CgenTab){
+            if(e.getSource() instanceof CgenTab) {
                 setSelectedComponent(cgenView);
+            } else if(e.getSource() instanceof DbImportTab) {
+                setSelectedComponent(dbImportScrollPane);
+            } else if(isCgenTabActive() || isDbImportTabActive()) {
+                fireStateChanged();
             }
         });
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GeneratorsPanel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GeneratorsPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GeneratorsPanel.java
new file mode 100644
index 0000000..d0de082
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GeneratorsPanel.java
@@ -0,0 +1,102 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.modeler.editor;
+
+import com.jgoodies.forms.builder.DefaultFormBuilder;
+import com.jgoodies.forms.layout.FormLayout;
+import org.apache.cayenne.configuration.xml.DataChannelMetaData;
+import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.util.ModelerUtil;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import java.awt.BorderLayout;
+
+/**
+ * @since 4.1
+ */
+public class GeneratorsPanel extends JPanel {
+
+    private JCheckBox checkConfig;
+    private JLabel dataMapLabel;
+    private JButton toConfigButton;
+    private JButton deleteButton;
+    private DataMap dataMap;
+    private Class type;
+    private String icon;
+
+    public GeneratorsPanel(DataMap dataMap, String icon, Class type) {
+        this.type = type;
+        this.icon = icon;
+        this.dataMap = dataMap;
+        initView();
+    }
+
+    public void initView(){
+        setLayout(new BorderLayout());
+        FormLayout layout = new FormLayout(
+                "left:pref, 4dlu, fill:50dlu, 3dlu, fill:120, 3dlu, fill:120", "");
+        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
+        builder.setDefaultDialogBorder();
+
+        this.checkConfig = new JCheckBox();
+        this.dataMapLabel = new JLabel(dataMap.getName());
+        DataChannelMetaData metaData = Application.getInstance().getMetaData();
+        this.toConfigButton = new JButton();
+        this.deleteButton = new JButton("Delete config");
+        if(metaData.get(dataMap, type) != null) {
+            this.toConfigButton.setText("Edit Config");
+        } else {
+            this.toConfigButton.setText("Create Config");
+            if(type == ReverseEngineering.class) {
+                checkConfig.setEnabled(false);
+            }
+        }
+        this.toConfigButton.setIcon(ModelerUtil.buildIcon(icon));
+        builder.append(checkConfig, dataMapLabel, toConfigButton);
+        if(type == ReverseEngineering.class) {
+            builder.append(deleteButton);
+        }
+        this.add(builder.getPanel(), BorderLayout.CENTER);
+    }
+
+    public JCheckBox getCheckConfig() {
+        return checkConfig;
+    }
+
+    public JButton getToConfigButton() {
+        return toConfigButton;
+    }
+
+    public JButton getDeleteButton() {
+        return deleteButton;
+    }
+
+    public JLabel getDataMapLabel() {
+        return dataMapLabel;
+    }
+
+    public DataMap getDataMap() {
+        return dataMap;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GeneratorsTab.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GeneratorsTab.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GeneratorsTab.java
new file mode 100644
index 0000000..a7e708a
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GeneratorsTab.java
@@ -0,0 +1,98 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.modeler.editor;
+
+import com.jgoodies.forms.builder.DefaultFormBuilder;
+import com.jgoodies.forms.layout.FormLayout;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.util.ModelerUtil;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * @since 4.1
+ */
+public class GeneratorsTab extends JPanel {
+
+    protected ProjectController projectController;
+    private GeneratorsTabController additionalTabController;
+
+    private JCheckBox selectAll;
+    private JButton generateAll;
+
+    public GeneratorsTab(ProjectController projectController, GeneratorsTabController additionalTabController, String icon) {
+        this.projectController = projectController;
+        this.additionalTabController = additionalTabController;
+        this.selectAll = new JCheckBox();
+        generateAll = new JButton("Run");
+        generateAll.setEnabled(false);
+        generateAll.setIcon(ModelerUtil.buildIcon(icon));
+        generateAll.setPreferredSize(new Dimension(120, 30));
+        generateAll.addActionListener(action -> additionalTabController.runGenerators(additionalTabController.getSelectedDataMaps()));
+        setLayout(new BorderLayout());
+    }
+
+    public void initView() {
+        removeAll();
+        additionalTabController.createPanels();
+        FormLayout layout = new FormLayout(
+                "left:pref, 4dlu, 50dlu", "");
+        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
+        builder.setDefaultDialogBorder();
+        ConcurrentMap<DataMap, GeneratorsPanel> panels = additionalTabController.getGeneratorsPanels();
+
+        if(panels.isEmpty()) {
+            this.add(new JLabel("There are no configs."), BorderLayout.NORTH);
+            return;
+        }
+
+        JPanel selectAllPanel = new JPanel(new FlowLayout());
+        selectAllPanel.add(new JLabel("Select All"), FlowLayout.LEFT);
+        selectAllPanel.add(selectAll, FlowLayout.CENTER);
+        builder.append(selectAllPanel);
+        builder.nextLine();
+
+        SortedSet<DataMap> keys = new TreeSet<>(panels.keySet());
+        for(DataMap dataMap : keys) {
+            builder.append(panels.get(dataMap));
+            builder.nextLine();
+        }
+        builder.append(generateAll);
+        this.add(builder.getPanel(), BorderLayout.CENTER);
+    }
+
+    public void showEmptyMessage() {
+        JOptionPane.showMessageDialog(
+                this,
+                "Nothing to generate");
+    }
+
+    public JCheckBox getSelectAll() {
+        return selectAll;
+    }
+
+    public JButton getGenerateAll() {
+        return generateAll;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GeneratorsTabController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GeneratorsTabController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GeneratorsTabController.java
new file mode 100644
index 0000000..847bd59
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GeneratorsTabController.java
@@ -0,0 +1,138 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.modeler.editor;
+
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.dialog.ErrorDebugDialog;
+import org.apache.cayenne.project.Project;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.awt.event.ItemEvent;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * @since 4.1
+ */
+public abstract class GeneratorsTabController {
+
+    public static Logger logObj = LoggerFactory.getLogger(ErrorDebugDialog.class);
+    public ProjectController projectController;
+    public GeneratorsTab view;
+    private Class type;
+
+    public ConcurrentMap<DataMap, GeneratorsPanel> generatorsPanels;
+    public Set<DataMap> selectedDataMaps;
+
+    public GeneratorsTabController(Class type) {
+        this.type = type;
+        this.generatorsPanels = new ConcurrentHashMap<>();
+        this.selectedDataMaps = new HashSet<>();
+    }
+
+    public String icon;
+
+    public abstract void runGenerators(Set<DataMap> dataMaps);
+
+    public void createPanels(){
+        Collection<DataMap> dataMaps = getDataMaps();
+        generatorsPanels.clear();
+        for(DataMap dataMap : dataMaps) {
+            GeneratorsPanel generatorPanel = new GeneratorsPanel(dataMap, "icon-datamap.png", type);
+            initListenersForPanel(generatorPanel);
+            generatorsPanels.put(dataMap, generatorPanel);
+        }
+        selectedDataMaps.forEach(dataMap -> {
+            if(generatorsPanels.get(dataMap) != null) {
+                GeneratorsPanel currPanel = generatorsPanels.get(dataMap);
+                currPanel.getCheckConfig().setSelected(true);
+            }
+        });
+    }
+
+    private void initListenersForPanel(GeneratorsPanel panel) {
+        panel.getCheckConfig().addItemListener(e -> {
+            if(e.getStateChange() == ItemEvent.SELECTED) {
+                selectedDataMaps.add(panel.getDataMap());
+            } else if(e.getStateChange() == ItemEvent.DESELECTED) {
+                selectedDataMaps.remove(panel.getDataMap());
+            }
+            setGenerateButtonDisabled();
+        });
+
+        panel.getToConfigButton().addActionListener(action -> showConfig(panel.getDataMap()));
+        panel.getDeleteButton().addActionListener(action -> deleteConfig(panel.getDataMap()));
+
+        view.getSelectAll().addItemListener(e -> {
+            if(e.getStateChange() == ItemEvent.SELECTED) {
+                getGeneratorsPanels().forEach((key, value) -> {
+                    if (value.getCheckConfig().isEnabled()) {
+                        value.getCheckConfig().setSelected(true);
+                    }
+                });
+            } else if(e.getStateChange() == ItemEvent.DESELECTED) {
+                getGeneratorsPanels().forEach((key, value) -> {
+                    if(value.getCheckConfig().isEnabled()) {
+                        value.getCheckConfig().setSelected(false);
+                    }
+                });
+            }
+            setGenerateButtonDisabled();
+        });
+    }
+
+    public abstract void showConfig(DataMap dataMap);
+
+    public abstract void deleteConfig(DataMap dataMap);
+
+    private void setGenerateButtonDisabled() {
+        if(selectedDataMaps.size() == 0) {
+            view.getGenerateAll().setEnabled(false);
+        } else {
+            view.getGenerateAll().setEnabled(true);
+        }
+    }
+
+    private Collection<DataMap> getDataMaps() {
+        Project project = projectController.getProject();
+        return  ((DataChannelDescriptor) project.getRootNode()).getDataMaps();
+    }
+
+    public GeneratorsTab getView() {
+        return view;
+    }
+
+    public ProjectController getProjectController() {
+        return projectController;
+    }
+
+    ConcurrentMap<DataMap, GeneratorsPanel> getGeneratorsPanels() {
+        return generatorsPanels;
+    }
+
+    Set<DataMap> getSelectedDataMaps() {
+        return selectedDataMaps;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GlobalDbImportController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GlobalDbImportController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GlobalDbImportController.java
new file mode 100644
index 0000000..582b2d4
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/GlobalDbImportController.java
@@ -0,0 +1,77 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.modeler.editor;
+
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.modeler.dialog.db.load.DbLoadResultDialog;
+
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableModel;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * @since 4.1
+ */
+public class GlobalDbImportController {
+
+    private static final String DIALOG_TITLE = "Reverse Engineering Result";
+
+    private DbLoadResultDialog dbLoadResultDialog;
+    private boolean globalImport;
+
+    public GlobalDbImportController() {
+        this.dbLoadResultDialog = new DbLoadResultDialog(DIALOG_TITLE);
+    }
+
+    public synchronized DbLoadResultDialog createDialog() {
+        return dbLoadResultDialog;
+    }
+
+    public void showDialog() {
+        dbLoadResultDialog.pack();
+        dbLoadResultDialog.setVisible(true);
+    }
+
+    public void setGlobalImport(boolean globalImport) {
+        this.globalImport = globalImport;
+    }
+
+    public boolean isGlobalImport() {
+        return globalImport;
+    }
+
+    public synchronized void checkImport(DataMap dataMap) {
+        dbLoadResultDialog.getTableForMap().remove(dataMap);
+    }
+
+    public void resetDialog() {
+        ConcurrentMap<DataMap, JTable> tableMap = dbLoadResultDialog.getTableForMap();
+        for(DataMap dataMap : tableMap.keySet()) {
+            JTable table = tableMap.get(dataMap);
+            DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
+            int rowCount = tableModel.getRowCount();
+            for (int i = rowCount - 1; i >= 0; i--) {
+                tableModel.removeRow(i);
+            }
+        }
+
+        dbLoadResultDialog.getTableForMap().clear();
+        dbLoadResultDialog.getTablePanel().removeAll();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/TabPanel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/TabPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/TabPanel.java
deleted file mode 100644
index c7f812b..0000000
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/TabPanel.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.apache.cayenne.modeler.editor;
-
-import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-import org.apache.cayenne.configuration.xml.DataChannelMetaData;
-import org.apache.cayenne.gen.CgenConfiguration;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.modeler.Application;
-import org.apache.cayenne.modeler.util.ModelerUtil;
-
-import javax.swing.*;
-import java.awt.*;
-
-public class TabPanel extends JPanel {
-
-    private JCheckBox checkConfig;
-    private JLabel dataMapLabel;
-    private JButton toConfigButton;
-    private DataMap dataMap;
-
-    public TabPanel(DataMap dataMap, String icon) {
-        setLayout(new BorderLayout());
-        FormLayout layout = new FormLayout(
-                "left:pref, 4dlu, fill:50dlu, 3dlu, fill:120", "");
-        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
-        builder.setDefaultDialogBorder();
-
-        this.dataMap = dataMap;
-        this.checkConfig = new JCheckBox();
-        this.dataMapLabel = new JLabel(dataMap.getName());
-        DataChannelMetaData metaData = Application.getInstance().getMetaData();
-        this.toConfigButton = new JButton();
-        if(metaData.get(dataMap, CgenConfiguration.class) != null) {
-            this.toConfigButton.setText("Edit Config");
-        } else {
-            this.toConfigButton.setText("Create Config");
-        }
-        this.toConfigButton.setIcon(ModelerUtil.buildIcon(icon));
-
-        builder.append(checkConfig, dataMapLabel, toConfigButton);
-        this.add(builder.getPanel(), BorderLayout.CENTER);
-    }
-
-    public JCheckBox getCheckConfig() {
-        return checkConfig;
-    }
-
-    public JButton getToConfigButton() {
-        return toConfigButton;
-    }
-
-    public JLabel getDataMapLabel() {
-        return dataMapLabel;
-    }
-
-    public DataMap getDataMap() {
-        return dataMap;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTab.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTab.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTab.java
index 9a6b0aa..c4f3330 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTab.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTab.java
@@ -20,17 +20,17 @@
 package org.apache.cayenne.modeler.editor.cgen.domain;
 
 import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.modeler.editor.AdditionalTab;
-import org.apache.cayenne.modeler.editor.AdditionalTabController;
+import org.apache.cayenne.modeler.editor.GeneratorsTab;
+import org.apache.cayenne.modeler.editor.GeneratorsTabController;
 
 import javax.swing.*;
 
 /**
  * @since 4.1
  */
-public class CgenTab extends AdditionalTab {
+public class CgenTab extends GeneratorsTab {
 
-    public CgenTab(ProjectController projectController, AdditionalTabController additionalTabController) {
+    public CgenTab(ProjectController projectController, GeneratorsTabController additionalTabController) {
         super(projectController, additionalTabController, "icon-gen_java.png");
     }
 
@@ -46,10 +46,4 @@ public class CgenTab extends AdditionalTab {
                 "Error generating classes - " + msg);
     }
 
-    void showEmptyMessage() {
-        JOptionPane.showMessageDialog(
-                this,
-                "Nothing to generate - ");
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTabController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTabController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTabController.java
index 59f29b0..1a171d7 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTabController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTabController.java
@@ -27,7 +27,7 @@ import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.dialog.pref.GeneralPreferences;
-import org.apache.cayenne.modeler.editor.AdditionalTabController;
+import org.apache.cayenne.modeler.editor.GeneratorsTabController;
 import org.apache.cayenne.modeler.event.DataMapDisplayEvent;
 import org.apache.cayenne.modeler.util.ModelerUtil;
 
@@ -36,27 +36,24 @@ import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.HashSet;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.prefs.Preferences;
 
 /**
  * @since 4.1
  */
-public class CgenTabController extends AdditionalTabController {
+public class CgenTabController extends GeneratorsTabController {
 
     public CgenTabController(ProjectController projectController) {
+        super(CgenConfiguration.class);
         this.projectController = projectController;
         this.view = new CgenTab(projectController, this);
-        this.generatorsPanels = new ConcurrentHashMap<>();
-        this.selectedDataMaps = new HashSet<>();
     }
 
     public void runGenerators(Set<DataMap> dataMaps) {
         DataChannelMetaData metaData = Application.getInstance().getMetaData();
         if(dataMaps.isEmpty()) {
-            ((CgenTab)view).showEmptyMessage();
+            view.showEmptyMessage();
             return;
         }
         boolean generationFail = false;
@@ -125,4 +122,9 @@ public class CgenTabController extends AdditionalTabController {
             projectController.fireDataMapDisplayEvent(new DataMapDisplayEvent(this.getView(), dataMap, dataMap.getDataChannelDescriptor()));
         }
     }
+
+    @Override
+    public void deleteConfig(DataMap dataMap) {
+        //NOOP
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportView.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportView.java
index 4c00c12..ecde553 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportView.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportView.java
@@ -30,13 +30,9 @@ import org.apache.cayenne.modeler.dialog.db.load.TransferableNode;
 import org.apache.cayenne.modeler.util.CayenneAction;
 import org.apache.cayenne.modeler.util.ModelerUtil;
 
-import javax.swing.AbstractAction;
-import javax.swing.ImageIcon;
-import javax.swing.JButton;
-import javax.swing.JPanel;
-import javax.swing.JProgressBar;
-import java.awt.BorderLayout;
-import java.awt.FlowLayout;
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
 import java.awt.event.ActionEvent;
 
 /**
@@ -77,18 +73,19 @@ public class DbImportView extends JPanel {
 
         FormLayout layout = new FormLayout(MAIN_LAYOUT);
         DefaultFormBuilder builder = new DefaultFormBuilder(layout);
-        builder.setDefaultDialogBorder();
-        builder.appendSeparator("Database Import Configuration");
         builder.append(treeToolbar, ALL_LINE_SPAN);
-
         FormLayout headerLayout = new FormLayout(HEADER_LAYOUT);
 
         DefaultFormBuilder reverseEngineeringHeaderBuilder = new DefaultFormBuilder(headerLayout);
-        reverseEngineeringHeaderBuilder.append("Import Configuration");
+        JLabel importLabel = new JLabel("Database Import Configuration");
+        importLabel.setBorder(new EmptyBorder(0, 5, 0,0));
+        reverseEngineeringHeaderBuilder.append(importLabel);
         builder.append(reverseEngineeringHeaderBuilder.getPanel());
 
         DefaultFormBuilder databaseHeaderBuilder = new DefaultFormBuilder(headerLayout);
-        databaseHeaderBuilder.append("Database Schema");
+        JLabel schemaLabel = new JLabel("Database Schema");
+        schemaLabel.setBorder(new EmptyBorder(0, 5, 0,0));
+        databaseHeaderBuilder.append(schemaLabel);
         LoadDbSchemaAction loadDbSchemaAction = projectController.getApplication().getActionManager().
                 getAction(LoadDbSchemaAction.class);
         loadDbSchemaAction.setDraggableTreePanel(draggableTreePanel);
@@ -190,8 +187,8 @@ public class DbImportView extends JPanel {
         treePanel.getReverseEngineeringTree().stopEditing();
         if (map != null) {
             treeToolbar.unlockButtons();
-            ReverseEngineering reverseEngineering = DbImportView.this.projectController.getApplication().
-                    getMetaData().get(map, ReverseEngineering.class);
+            ReverseEngineering reverseEngineering = DbImportView.this.projectController.getApplication()
+                    .getMetaData().get(map, ReverseEngineering.class);
             if (reverseEngineering == null) {
                 reverseEngineering = new ReverseEngineering();
                 DbImportView.this.projectController.getApplication().getMetaData().add(map, reverseEngineering);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/TreeToolbarPanel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/TreeToolbarPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/TreeToolbarPanel.java
index cb1ee9b..97303b0 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/TreeToolbarPanel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/TreeToolbarPanel.java
@@ -29,6 +29,7 @@ import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable;
 import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
 import org.apache.cayenne.dbsync.reverse.dbimport.Schema;
 import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.action.GetDbConnectionAction;
 import org.apache.cayenne.modeler.action.dbimport.AddCatalogAction;
 import org.apache.cayenne.modeler.action.dbimport.AddExcludeColumnAction;
 import org.apache.cayenne.modeler.action.dbimport.AddExcludeProcedureAction;
@@ -40,14 +41,12 @@ import org.apache.cayenne.modeler.action.dbimport.AddPatternParamAction;
 import org.apache.cayenne.modeler.action.dbimport.AddSchemaAction;
 import org.apache.cayenne.modeler.action.dbimport.DeleteNodeAction;
 import org.apache.cayenne.modeler.action.dbimport.EditNodeAction;
-import org.apache.cayenne.modeler.action.GetDbConnectionAction;
 import org.apache.cayenne.modeler.action.dbimport.TreeManipulationAction;
 import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;
-import org.apache.cayenne.modeler.editor.dbimport.DbImportTree;
-import org.apache.cayenne.modeler.editor.dbimport.DraggableTreePanel;
 
 import javax.swing.JButton;
 import javax.swing.JToolBar;
+import javax.swing.border.EmptyBorder;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -80,6 +79,7 @@ class TreeToolbarPanel extends JToolBar {
         createButtons(treePanel);
         initLevels();
         addButtons();
+        this.setBorder(new EmptyBorder(0,0,0,0));
     }
 
     void unlockButtons() {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/domain/DbImportTab.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/domain/DbImportTab.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/domain/DbImportTab.java
new file mode 100644
index 0000000..14ca9af
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/domain/DbImportTab.java
@@ -0,0 +1,34 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.modeler.editor.dbimport.domain;
+
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.editor.GeneratorsTab;
+import org.apache.cayenne.modeler.editor.GeneratorsTabController;
+
+/**
+ * @since 4.1
+ */
+public class DbImportTab extends GeneratorsTab {
+
+    public DbImportTab(ProjectController projectController, GeneratorsTabController additionalTabController) {
+        super(projectController, additionalTabController, "icon-dbi-runImport.png");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5a0b4a76/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/domain/DbImportTabController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/domain/DbImportTabController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/domain/DbImportTabController.java
new file mode 100644
index 0000000..c65529b
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/domain/DbImportTabController.java
@@ -0,0 +1,78 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.modeler.editor.dbimport.domain;
+
+import org.apache.cayenne.configuration.xml.DataChannelMetaData;
+import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.action.ReverseEngineeringAction;
+import org.apache.cayenne.modeler.editor.GeneratorsTabController;
+import org.apache.cayenne.modeler.editor.GeneratorsPanel;
+import org.apache.cayenne.modeler.event.DataMapDisplayEvent;
+
+import java.util.Set;
+
+/**
+ * @since 4.1
+ */
+public class DbImportTabController extends GeneratorsTabController {
+
+    public DbImportTabController(ProjectController projectController) {
+        super(ReverseEngineering.class);
+        this.projectController = projectController;
+        this.view = new DbImportTab(projectController, this);
+    }
+
+    @Override
+    public void runGenerators(Set<DataMap> dataMaps) {
+        if(dataMaps.isEmpty()) {
+            view.showEmptyMessage();
+            return;
+        }
+        Application.getInstance().getFrameController().getGlobalDbImportController().setGlobalImport(true);
+        ReverseEngineeringAction reverseEngineeringAction = Application.getInstance().getActionManager().getAction(ReverseEngineeringAction.class);
+        for(DataMap dataMap : dataMaps) {
+            projectController.setCurrentDataMap(dataMap);
+            reverseEngineeringAction.performAction();
+        }
+    }
+
+    @Override
+    public void showConfig(DataMap dataMap) {
+        if (dataMap != null) {
+            projectController.fireDataMapDisplayEvent(new DataMapDisplayEvent(this.getView(), dataMap, dataMap.getDataChannelDescriptor()));
+        }
+    }
+
+    @Override
+    public void deleteConfig(DataMap dataMap) {
+        DataChannelMetaData metaData = Application.getInstance().getMetaData();
+        if(metaData != null) {
+            ReverseEngineering reverseEngineering = metaData.remove(dataMap, ReverseEngineering.class);
+            if(reverseEngineering != null) {
+                GeneratorsPanel tabPanel = generatorsPanels.get(dataMap);
+                tabPanel.getToConfigButton().setText("Create Config");
+                tabPanel.getCheckConfig().setEnabled(false);
+                tabPanel.getCheckConfig().setSelected(false);
+            }
+        }
+    }
+}