// -*- mode: java; c-basic-offset: 2; -*- // Copyright 2009-2011 Google, All Rights reserved // Copyright 2011-2015 MIT, All rights reserved // Released under the Apache License, Version 2.0 // http://www.apache.org/licenses/LICENSE-2.0 package com.google.appinventor.client.wizards; import static com.google.appinventor.client.Ode.MESSAGES; import com.allen_sauer.gwt.dnd.client.util.StringUtil; import com.google.appinventor.client.Ode; import com.google.appinventor.client.OdeAsyncCallback; import com.google.appinventor.client.editor.simple.SimpleComponentDatabase; import com.google.appinventor.client.editor.youngandroid.YaProjectEditor; import com.google.appinventor.client.explorer.project.Project; import com.google.appinventor.client.output.OdeLog; import com.google.appinventor.common.utils.StringUtils; import com.google.appinventor.client.utils.Uploader; import com.google.appinventor.shared.rpc.ServerLayout; import com.google.appinventor.shared.rpc.UploadResponse; import com.google.appinventor.shared.rpc.component.Component; import com.google.appinventor.shared.rpc.component.ComponentImportResponse; import com.google.appinventor.shared.rpc.project.ProjectNode; import com.google.appinventor.shared.rpc.project.youngandroid.YoungAndroidAssetsFolder; import com.google.appinventor.shared.rpc.project.youngandroid.YoungAndroidComponentsFolder; import com.google.appinventor.shared.rpc.project.youngandroid.YoungAndroidProjectNode; import com.google.gwt.core.client.GWT; import com.google.gwt.user.cellview.client.CellTable; import com.google.gwt.user.cellview.client.Column; import com.google.gwt.user.client.Command; import com.google.gwt.cell.client.CheckboxCell; import com.google.gwt.cell.client.NumberCell; import com.google.gwt.cell.client.TextCell; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.FileUpload; import com.google.gwt.user.client.ui.Grid; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.TabPanel; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.view.client.ListDataProvider; import com.google.gwt.view.client.SingleSelectionModel; import java.util.List; public class ComponentImportWizard extends Wizard { final static String external_components = "assets/external_comps/"; private static class ImportComponentCallback extends OdeAsyncCallback<ComponentImportResponse> { @Override public void onSuccess(ComponentImportResponse response) { if (response.getStatus() == ComponentImportResponse.Status.FAILED){ Window.alert(MESSAGES.componentImportError()); return; } else if (response.getStatus() != ComponentImportResponse.Status.IMPORTED && response.getStatus() != ComponentImportResponse.Status.UPGRADED) { Window.alert(MESSAGES.componentImportError()); return; } else if (response.getStatus() == ComponentImportResponse.Status.UNKNOWN_URL) { Window.alert(MESSAGES.componentImportUnknownURLError()); } else if (response.getStatus() == ComponentImportResponse.Status.UPGRADED) { String componentName = SimpleComponentDatabase.getInstance().getComponentName(response.getComponentType()); Window.alert(MESSAGES.componentUpgradedAlert() + componentName + " !"); } List<ProjectNode> compNodes = response.getNodes(); long destinationProjectId = response.getProjectId(); long currentProjectId = ode.getCurrentYoungAndroidProjectId(); if (currentProjectId != destinationProjectId) { return; // User switched project early! } Project project = ode.getProjectManager().getProject(destinationProjectId); if (project == null) { return; // Project does not exist! } if (response.getStatus() == ComponentImportResponse.Status.UPGRADED || response.getStatus() == ComponentImportResponse.Status.IMPORTED) { YoungAndroidComponentsFolder componentsFolder = ((YoungAndroidProjectNode) project.getRootNode()).getComponentsFolder(); YaProjectEditor projectEditor = (YaProjectEditor) ode.getEditorManager().getOpenProjectEditor(destinationProjectId); if (projectEditor == null) { return; // Project is not open! } for (ProjectNode node : compNodes) { project.addNode(componentsFolder, node); if ((node.getName().equals("component.json") || node.getName().equals("components.json")) && StringUtils.countMatches(node.getFileId(), "/") == 3) { projectEditor.addComponent(node, null); } } } } } private static int FROM_MY_COMPUTER_TAB = 0; private static int URL_TAB = 1; private static final String COMPONENT_ARCHIVE_EXTENSION = ".aix"; private static final Ode ode = Ode.getInstance(); public ComponentImportWizard() { super(MESSAGES.componentImportWizardCaption(), true, false); final CellTable compTable = createCompTable(); final FileUpload fileUpload = createFileUpload(); final Grid urlGrid = createUrlGrid(); final TabPanel tabPanel = new TabPanel(); tabPanel.add(fileUpload, "From my computer"); tabPanel.add(urlGrid, "URL"); tabPanel.selectTab(FROM_MY_COMPUTER_TAB); tabPanel.addStyleName("ode-Tabpanel"); VerticalPanel panel = new VerticalPanel(); panel.add(tabPanel); addPage(panel); getConfirmButton().setText("Import"); setPagePanelHeight(150); setPixelSize(200, 150); setStylePrimaryName("ode-DialogBox"); initFinishCommand(new Command() { @Override public void execute() { final long projectId = ode.getCurrentYoungAndroidProjectId(); final Project project = ode.getProjectManager().getProject(projectId); final YoungAndroidAssetsFolder assetsFolderNode = ((YoungAndroidProjectNode) project.getRootNode()).getAssetsFolder(); if (tabPanel.getTabBar().getSelectedTab() == URL_TAB) { TextBox urlTextBox = (TextBox) urlGrid.getWidget(1, 0); String url = urlTextBox.getText(); if (url.trim().isEmpty()) { Window.alert(MESSAGES.noUrlError()); return; } ode.getComponentService().importComponentToProject(url, projectId, assetsFolderNode.getFileId(), new ImportComponentCallback()); } else if (tabPanel.getTabBar().getSelectedTab() == FROM_MY_COMPUTER_TAB) { if (!fileUpload.getFilename().endsWith(COMPONENT_ARCHIVE_EXTENSION)) { Window.alert(MESSAGES.notComponentArchiveError()); return; } String url = GWT.getModuleBaseURL() + ServerLayout.UPLOAD_SERVLET + "/" + ServerLayout.UPLOAD_COMPONENT + "/" + trimLeadingPath(fileUpload.getFilename()); Uploader.getInstance().upload(fileUpload, url, new OdeAsyncCallback<UploadResponse>() { @Override public void onSuccess(UploadResponse uploadResponse) { String toImport = uploadResponse.getInfo(); ode.getComponentService().importComponentToProject(toImport, projectId, assetsFolderNode.getFileId(), new ImportComponentCallback()); } }); return; } } private String trimLeadingPath(String filename) { // Strip leading path off filename. // We need to support both Unix ('/') and Windows ('\\') separators. return filename.substring(Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\')) + 1); } }); } private CellTable createCompTable() { final SingleSelectionModel<Component> selectionModel = new SingleSelectionModel<Component>(); CellTable<Component> compTable = new CellTable<Component>(); compTable.setSelectionModel(selectionModel); Column<Component, Boolean> checkColumn = new Column<Component, Boolean>(new CheckboxCell(true, false)) { @Override public Boolean getValue(Component comp) { return selectionModel.isSelected(comp); } }; Column<Component, String> nameColumn = new Column<Component, String>(new TextCell()) { @Override public String getValue(Component comp) { return comp.getName(); } }; Column<Component, Number> versionColumn = new Column<Component, Number>(new NumberCell()) { @Override public Number getValue(Component comp) { return comp.getVersion(); } }; compTable.addColumn(checkColumn); compTable.addColumn(nameColumn, "Component"); compTable.addColumn(versionColumn, "Version"); return compTable; } private Grid createUrlGrid() { TextBox urlTextBox = new TextBox(); urlTextBox.setWidth("100%"); Grid grid = new Grid(2, 1); grid.setWidget(0, 0, new Label("Url:")); grid.setWidget(1, 0, urlTextBox); return grid; } private FileUpload createFileUpload() { FileUpload upload = new FileUpload(); upload.setName(ServerLayout.UPLOAD_COMPONENT_ARCHIVE_FORM_ELEMENT); return upload; } }