/* * DBeaver - Universal Database Manager * Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org) * * Licensed 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.jkiss.dbeaver.ui.dialogs.driver; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TreeEditor; import org.eclipse.swt.events.*; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.*; import org.jkiss.dbeaver.core.DBeaverUI; import org.jkiss.dbeaver.model.connection.DBPDriver; import org.jkiss.dbeaver.model.connection.DBPDriverDependencies; import org.jkiss.dbeaver.model.connection.DBPDriverLibrary; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.runtime.DBRRunnableContext; import org.jkiss.dbeaver.model.runtime.DBRRunnableWithProgress; import org.jkiss.dbeaver.registry.driver.DriverDependencies; import org.jkiss.dbeaver.ui.DBeaverIcons; import org.jkiss.dbeaver.ui.UIUtils; import org.jkiss.utils.CommonUtils; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.List; class DriverDependenciesTree { private DBRRunnableContext runnableContext; private DBPDriver driver; private Collection<? extends DBPDriverLibrary> libraries; private final DriverDependencies dependencies; private boolean editable; private Tree filesTree; private TreeEditor treeEditor; private Font boldFont; public DriverDependenciesTree(Composite parent, DBRRunnableContext runnableContext, DriverDependencies dependencies, DBPDriver driver, Collection<? extends DBPDriverLibrary> libraries, boolean editable) { this.runnableContext = runnableContext; this.driver = driver; this.libraries = libraries; this.dependencies = dependencies; this.editable = editable; filesTree = new Tree(parent, SWT.BORDER | SWT.FULL_SELECTION); filesTree.setHeaderVisible(true); final GridData gd = new GridData(GridData.FILL_BOTH); gd.minimumHeight = filesTree.getHeaderHeight() + filesTree.getItemHeight() * 3; filesTree.setLayoutData(gd); UIUtils.createTreeColumn(filesTree, SWT.LEFT, "File"); UIUtils.createTreeColumn(filesTree, SWT.LEFT, "Version"); UIUtils.createTreeColumn(filesTree, SWT.LEFT, "Description"); if (editable) { boldFont = UIUtils.makeBoldFont(filesTree.getFont()); treeEditor = new TreeEditor(filesTree); treeEditor.horizontalAlignment = SWT.RIGHT; treeEditor.verticalAlignment = SWT.CENTER; treeEditor.grabHorizontal = true; treeEditor.minimumWidth = 50; filesTree.addMouseListener(new MouseAdapter() { @Override public void mouseUp(MouseEvent e) { TreeItem item = filesTree.getItem(new Point(e.x, e.y)); if (item != null && item.getData() instanceof DBPDriverDependencies.DependencyNode) { if (UIUtils.getColumnAtPos(item, e.x, e.y) == 1) { showVersionEditor(item); return; } } disposeOldEditor(); } }); filesTree.addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { UIUtils.dispose(boldFont); } }); } } public Tree getTree() { return filesTree; } public DBPDriver getDriver() { return driver; } public Collection<? extends DBPDriverLibrary> getLibraries() { return libraries; } public boolean resolveLibraries() { boolean resolved = false; try { runnableContext.run(true, true, new DBRRunnableWithProgress() { @Override public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask("Resolve dependencies", 100); try { dependencies.resolveDependencies(monitor); } catch (Exception e) { throw new InvocationTargetException(e); } finally { monitor.done(); } } }); resolved = true; } catch (InterruptedException e) { // User just canceled download } catch (InvocationTargetException e) { UIUtils.showErrorDialog(null, "Resolve libraries", "Error resolving driver libraries", e.getTargetException()); } filesTree.removeAll(); int totalItems = 1; for (DBPDriverDependencies.DependencyNode node : dependencies.getLibraryMap()) { DBPDriverLibrary library = node.library; TreeItem item = new TreeItem(filesTree, SWT.NONE); item.setData(node); item.setImage(DBeaverIcons.getImage(library.getIcon())); item.setText(0, library.getDisplayName()); item.setText(1, CommonUtils.notEmpty(library.getVersion())); item.setText(2, CommonUtils.notEmpty(library.getDescription())); if (editable) { item.setFont(1, boldFont); } totalItems++; if (addDependencies(item, node)) { item.setExpanded(true); totalItems += item.getItemCount(); } } UIUtils.packColumns(filesTree); // Check missing files int missingFiles = 0; for (DBPDriverDependencies.DependencyNode node : dependencies.getLibraryList()) { File localFile = node.library.getLocalFile(); if (localFile == null || !localFile.exists()) { missingFiles++; } } if (missingFiles == 0) { // UIUtils.showMessageBox(getShell(), "Driver Download", "All driver files are present", SWT.ICON_INFORMATION); // ((DriverDownloadDialog)getWizard().getContainer()).closeWizard(); } return resolved; } public void resizeTree() { Shell shell = filesTree.getShell(); Point curSize = shell.getSize(); int itemHeight = filesTree.getItemHeight(); shell.setSize(curSize.x, Math.min( (int)(DBeaverUI.getActiveWorkbenchWindow().getShell().getSize().y * 0.66), shell.computeSize(SWT.DEFAULT, SWT.DEFAULT).y) + itemHeight * 2); shell.layout(); } private boolean addDependencies(TreeItem parent, DBPDriverDependencies.DependencyNode node) { Collection<DBPDriverDependencies.DependencyNode> dependencies = node.dependencies; if (dependencies != null && !dependencies.isEmpty()) { for (DBPDriverDependencies.DependencyNode dep : dependencies) { TreeItem item = new TreeItem(parent, SWT.NONE); //item.setData(dep); item.setImage(DBeaverIcons.getImage(dep.library.getIcon())); item.setText(0, dep.library.getDisplayName()); item.setText(1, CommonUtils.notEmpty(dep.library.getVersion())); item.setText(2, CommonUtils.notEmpty(dep.library.getDescription())); if (dep.duplicate) { item.setForeground(filesTree.getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); } else { addDependencies(item, dep); } } return true; } return false; } private void disposeOldEditor() { if (treeEditor.getEditor() != null) { treeEditor.getEditor().dispose(); } Control oldEditor = treeEditor.getEditor(); if (oldEditor != null) oldEditor.dispose(); } private void showVersionEditor(final TreeItem item) { disposeOldEditor(); final DBPDriverDependencies.DependencyNode dependencyNode = (DBPDriverDependencies.DependencyNode) item.getData(); if (dependencyNode == null || dependencyNode.library == null || !dependencyNode.library.isDownloadable()) { return; } final List<String> allVersions = new ArrayList<>(); try { runnableContext.run(true, true, new DBRRunnableWithProgress() { @Override public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { allVersions.addAll( dependencyNode.library.getAvailableVersions(monitor)); } catch (IOException e) { throw new InvocationTargetException(e); } } }); } catch (InvocationTargetException e) { UIUtils.showErrorDialog(filesTree.getShell(), "Versions", "Error reading versions", e.getTargetException()); return; } catch (InterruptedException e) { return; } final String currentVersion = dependencyNode.library.getVersion(); if (currentVersion != null && !allVersions.contains(currentVersion)) { allVersions.add(currentVersion); } final Combo editor = new Combo(filesTree, SWT.DROP_DOWN | SWT.READ_ONLY); int versionIndex = -1; for (int i = 0; i < allVersions.size(); i++) { String version = allVersions.get(i); editor.add(version); if (version.equals(currentVersion)) { versionIndex = i; } } if (versionIndex >= 0) { editor.select(versionIndex); } editor.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { String newVersion = editor.getItem(editor.getSelectionIndex()); disposeOldEditor(); setLibraryVersion(dependencyNode.library, newVersion); } }); treeEditor.setEditor(editor, item, 1); editor.setListVisible(true); } // This may be overrided protected void setLibraryVersion(DBPDriverLibrary library, String version) { } }