blob: 2b5a18666f3318969c715ff3ad794c781d2f5749 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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 com.android.tools.idea.updater.configure;
import com.android.sdklib.AndroidVersion;
import com.android.sdklib.repository.descriptors.PkgType;
import com.android.tools.idea.sdk.remote.UpdatablePkgInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.collect.TreeMultimap;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.dualView.TreeTableView;
import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
import com.intellij.ui.treeStructure.treetable.TreeColumnInfo;
import com.intellij.util.ui.AsyncProcessIcon;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.tree.TreeUtil;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.*;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
/**
* Panel that shows all the packages corresponding to an AndroidVersion.
*/
public class PlatformComponentsPanel {
private TreeTableView myPlatformSummaryTable;
private TreeTableView myPlatformDetailTable;
private JPanel myPlatformPanel;
private JCheckBox myPlatformDetailsCheckbox;
private JPanel myPlatformLoadingPanel;
private JBLabel myPlatformLoadingLabel;
private AsyncProcessIcon myPlatformLoadingIcon;
private JPanel myRootPanel;
private boolean myModified;
private boolean myIncludePreview;
private UpdaterTreeNode myPlatformDetailsRootNode;
private UpdaterTreeNode myPlatformSummaryRootNode;
Set<NodeStateHolder> myStates = Sets.newHashSet();
// map of versions to current subpackages
Multimap<AndroidVersion, UpdatablePkgInfo> myCurrentPackages = TreeMultimap.create();
private final ChangeListener myModificationListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
refreshModified();
}
};
public PlatformComponentsPanel() {
myPlatformSummaryTable.setColumnSelectionAllowed(false);
myPlatformLoadingLabel.setForeground(JBColor.GRAY);
myPlatformDetailsCheckbox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updatePlatformTable();
}
});
}
private void updatePlatformTable() {
((CardLayout)myPlatformPanel.getLayout()).show(myPlatformPanel, myPlatformDetailsCheckbox.isSelected() ? "details" : "summary");
}
private void updatePlatformItems() {
myPlatformDetailsRootNode.removeAllChildren();
myPlatformSummaryRootNode.removeAllChildren();
myStates.clear();
List<AndroidVersion> versions = Lists.newArrayList(myCurrentPackages.keySet());
versions = Lists.reverse(versions);
for (AndroidVersion version : versions) {
Set<UpdaterTreeNode> versionNodes = Sets.newHashSet();
UpdaterTreeNode marker = new ParentTreeNode(version);
myPlatformDetailsRootNode.add(marker);
boolean obsolete = false;
for (UpdatablePkgInfo info : myCurrentPackages.get(version)) {
NodeStateHolder holder = new NodeStateHolder(info);
myStates.add(holder);
UpdaterTreeNode node = new PlatformDetailsTreeNode(holder, myIncludePreview, myModificationListener);
marker.add(node);
versionNodes.add(node);
if (info.getPkgDesc(myIncludePreview).isObsolete() && info.getPkgDesc(myIncludePreview).getType() == PkgType.PKG_PLATFORM) {
obsolete = true;
}
}
if (!obsolete) {
myPlatformSummaryRootNode.add(new SummaryTreeNode(version, versionNodes));
}
}
refreshModified();
myPlatformDetailTable.updateUI();
myPlatformSummaryTable.updateUI();
TreeUtil.expandAll(myPlatformDetailTable.getTree());
TreeUtil.expandAll(myPlatformSummaryTable.getTree());
}
public void startLoading() {
myCurrentPackages.clear();
myPlatformLoadingPanel.setVisible(true);
}
public void finishLoading() {
updatePlatformItems();
myPlatformLoadingPanel.setVisible(false);
}
private void createUIComponents() {
UpdaterTreeNode.Renderer renderer = new SummaryTreeNode.Renderer();
myPlatformLoadingIcon = new AsyncProcessIcon("Loading...");
myPlatformSummaryRootNode = new RootNode();
myPlatformDetailsRootNode = new RootNode();
ColumnInfo[] platformSummaryColumns =
new ColumnInfo[]{new DownloadStatusColumnInfo(), new TreeColumnInfo("Name"), new ApiLevelColumnInfo(), new RevisionColumnInfo(),
new StatusColumnInfo()};
myPlatformSummaryTable = new TreeTableView(new ListTreeTableModelOnColumns(myPlatformSummaryRootNode, platformSummaryColumns));
SdkUpdaterConfigPanel.setTreeTableProperties(myPlatformSummaryTable, renderer, myModificationListener);
ColumnInfo[] platformDetailColumns =
new ColumnInfo[]{new DownloadStatusColumnInfo(), new TreeColumnInfo("Name"), new ApiLevelColumnInfo(), new RevisionColumnInfo(),
new StatusColumnInfo()};
myPlatformDetailTable = new TreeTableView(new ListTreeTableModelOnColumns(myPlatformDetailsRootNode, platformDetailColumns));
SdkUpdaterConfigPanel.setTreeTableProperties(myPlatformDetailTable, renderer, myModificationListener);
}
public void setPackages(Multimap<AndroidVersion, UpdatablePkgInfo> packages) {
myCurrentPackages = packages;
updatePlatformItems();
}
public boolean isModified() {
return myModified;
}
public void refreshModified() {
Enumeration items = myPlatformDetailsRootNode.breadthFirstEnumeration();
while (items.hasMoreElements()) {
UpdaterTreeNode node = (UpdaterTreeNode)items.nextElement();
if (node.getInitialState() != node.getCurrentState()) {
myModified = true;
return;
}
}
myModified = false;
}
public void reset() {
for (Enumeration children = myPlatformDetailsRootNode.breadthFirstEnumeration(); children.hasMoreElements(); ) {
UpdaterTreeNode node = (UpdaterTreeNode)children.nextElement();
node.resetState();
}
refreshModified();
}
public void clearState() {
myStates.clear();
}
/**
* After changing whether previews are included, setPackages() must be called again with appropriately filtered packages.
*/
public void setIncludePreview(boolean includePreview) {
myIncludePreview = includePreview;
}
public void setEnabled(boolean enabled) {
myPlatformDetailTable.setEnabled(enabled);
myPlatformSummaryTable.setEnabled(enabled);
myPlatformDetailsCheckbox.setEnabled(enabled);
}
}