2 * Copyright (C) 2009 The Android Open Source Project
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
17 package com.android.sdkuilib.internal.repository;
\r
19 import com.android.sdklib.internal.repository.Archive;
\r
20 import com.android.sdklib.internal.repository.IDescription;
\r
21 import com.android.sdklib.internal.repository.Package;
\r
22 import com.android.sdkuilib.repository.UpdaterWindow.ISdkListener;
\r
24 import org.eclipse.jface.dialogs.MessageDialog;
\r
25 import org.eclipse.jface.viewers.ISelection;
\r
26 import org.eclipse.jface.viewers.IStructuredSelection;
\r
27 import org.eclipse.jface.viewers.TableViewer;
\r
28 import org.eclipse.swt.SWT;
\r
29 import org.eclipse.swt.events.ControlAdapter;
\r
30 import org.eclipse.swt.events.ControlEvent;
\r
31 import org.eclipse.swt.events.SelectionAdapter;
\r
32 import org.eclipse.swt.events.SelectionEvent;
\r
33 import org.eclipse.swt.graphics.Rectangle;
\r
34 import org.eclipse.swt.layout.GridData;
\r
35 import org.eclipse.swt.layout.GridLayout;
\r
36 import org.eclipse.swt.widgets.Button;
\r
37 import org.eclipse.swt.widgets.Composite;
\r
38 import org.eclipse.swt.widgets.Group;
\r
39 import org.eclipse.swt.widgets.Label;
\r
40 import org.eclipse.swt.widgets.Table;
\r
41 import org.eclipse.swt.widgets.TableColumn;
\r
42 import org.eclipse.swt.widgets.Text;
\r
44 import java.io.File;
\r
48 * - select => update desc, enable update + delete, enable home page if url
\r
49 * - home page callback
\r
52 * - refresh callback
\r
55 public class LocalPackagesPage extends Composite implements ISdkListener {
\r
57 private final UpdaterData mUpdaterData;
\r
59 private Label mSdkLocLabel;
\r
60 private Text mSdkLocText;
\r
61 private Button mSdkLocBrowse;
\r
62 private TableViewer mTableViewerPackages;
\r
63 private Table mTablePackages;
\r
64 private TableColumn mColumnPackages;
\r
65 private Group mDescriptionContainer;
\r
66 private Composite mContainerButtons;
\r
67 private Button mUpdateButton;
\r
68 private Label mPlaceholder1;
\r
69 private Button mDeleteButton;
\r
70 private Label mPlaceholder2;
\r
71 private Button mRefreshButton;
\r
72 private Label mDescriptionLabel;
\r
76 * Create the composite.
\r
77 * @param parent The parent of the composite.
\r
78 * @param updaterData An instance of {@link UpdaterData}.
\r
80 public LocalPackagesPage(Composite parent, UpdaterData updaterData) {
\r
81 super(parent, SWT.BORDER);
\r
83 mUpdaterData = updaterData;
\r
85 createContents(this);
\r
86 postCreate(); //$hide$
\r
89 private void createContents(Composite parent) {
\r
90 parent.setLayout(new GridLayout(3, false));
\r
92 createSdkLocation(parent);
\r
94 mTableViewerPackages = new TableViewer(parent, SWT.BORDER | SWT.FULL_SELECTION);
\r
95 mTablePackages = mTableViewerPackages.getTable();
\r
96 mTablePackages.setHeaderVisible(true);
\r
97 mTablePackages.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
\r
98 mTablePackages.addSelectionListener(new SelectionAdapter() {
\r
100 public void widgetSelected(SelectionEvent e) {
\r
101 onTreeSelected(); //$hide$
\r
105 mColumnPackages = new TableColumn(mTablePackages, SWT.NONE);
\r
106 mColumnPackages.setWidth(377);
\r
107 mColumnPackages.setText("Installed Packages");
\r
109 mDescriptionContainer = new Group(parent, SWT.NONE);
\r
110 mDescriptionContainer.setLayout(new GridLayout(1, false));
\r
111 mDescriptionContainer.setText("Description");
\r
112 mDescriptionContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
\r
114 mDescriptionLabel = new Label(mDescriptionContainer, SWT.NONE);
\r
115 mDescriptionLabel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true, 1, 1));
\r
116 mDescriptionLabel.setText("Line1\nLine2\nLine3");
\r
118 mContainerButtons = new Composite(parent, SWT.NONE);
\r
119 mContainerButtons.setLayout(new GridLayout(5, false));
\r
120 mContainerButtons.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
\r
122 mUpdateButton = new Button(mContainerButtons, SWT.NONE);
\r
123 mUpdateButton.setText("Update All...");
\r
124 mUpdateButton.addSelectionListener(new SelectionAdapter() {
\r
126 public void widgetSelected(SelectionEvent e) {
\r
127 onUpdateSelected(); //$hide$ (hide from SWT designer)
\r
131 mPlaceholder1 = new Label(mContainerButtons, SWT.NONE);
\r
132 mPlaceholder1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
\r
134 mDeleteButton = new Button(mContainerButtons, SWT.NONE);
\r
135 mDeleteButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
\r
136 mDeleteButton.setText("Delete...");
\r
137 mDeleteButton.addSelectionListener(new SelectionAdapter() {
\r
139 public void widgetSelected(SelectionEvent e) {
\r
140 onDeleteSelected(); //$hide$ (hide from SWT designer)
\r
144 mPlaceholder2 = new Label(mContainerButtons, SWT.NONE);
\r
145 mPlaceholder2.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
\r
147 mRefreshButton = new Button(mContainerButtons, SWT.NONE);
\r
148 mRefreshButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
\r
149 mRefreshButton.setText("Refresh");
\r
150 mRefreshButton.addSelectionListener(new SelectionAdapter() {
\r
152 public void widgetSelected(SelectionEvent e) {
\r
153 onRefreshSelected(); //$hide$ (hide from SWT designer)
\r
158 private void createSdkLocation(Composite parent) {
\r
159 mSdkLocLabel = new Label(parent, SWT.NONE);
\r
160 mSdkLocLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
\r
161 mSdkLocLabel.setText("SDK Location:");
\r
163 // If the sdk path is not user-customizable, do not create
\r
164 // the browse button and use horizSpan=2 on the text field.
\r
166 mSdkLocText = new Text(parent, SWT.BORDER);
\r
167 mSdkLocText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
\r
169 if (mUpdaterData.canUserChangeSdkRoot()) {
\r
170 mSdkLocBrowse = new Button(parent, SWT.NONE);
\r
171 mSdkLocBrowse.setText("Browse...");
\r
173 mSdkLocText.setEditable(false);
\r
174 ((GridData)mSdkLocText.getLayoutData()).horizontalSpan++;
\r
177 if (mUpdaterData.getOsSdkRoot() != null) {
\r
178 mSdkLocText.setText(mUpdaterData.getOsSdkRoot());
\r
183 public void dispose() {
\r
184 mUpdaterData.removeListener(this);
\r
189 protected void checkSubclass() {
\r
190 // Disable the check that prevents subclassing of SWT components
\r
193 // -- Start of internal part ----------
\r
194 // Hide everything down-below from SWT designer
\r
198 * Called by the constructor right after {@link #createContents(Composite)}.
\r
200 private void postCreate() {
\r
201 mUpdaterData.addListeners(this);
\r
202 adjustColumnsWidth();
\r
203 updateButtonsState();
\r
207 * Adds a listener to adjust the columns width when the parent is resized.
\r
209 * If we need something more fancy, we might want to use this:
\r
210 * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co
\r
212 private void adjustColumnsWidth() {
\r
213 // Add a listener to resize the column to the full width of the table
\r
214 ControlAdapter resizer = new ControlAdapter() {
\r
216 public void controlResized(ControlEvent e) {
\r
217 Rectangle r = mTablePackages.getClientArea();
\r
218 mColumnPackages.setWidth(r.width);
\r
221 mTablePackages.addControlListener(resizer);
\r
222 resizer.controlResized(null);
\r
226 * Enable or disable buttons depending on list content and selection
\r
228 private void updateButtonsState() {
\r
229 ISelection sel = mTableViewerPackages.getSelection();
\r
230 boolean hasSelection = sel != null && !sel.isEmpty();
\r
232 mUpdateButton.setEnabled(mTablePackages.getItemCount() > 0);
\r
233 mDeleteButton.setEnabled(hasSelection);
\r
234 mRefreshButton.setEnabled(true);
\r
238 * Called when an item in the package table viewer is selected.
\r
239 * If the items is an {@link IDescription} (as it should), this will display its long
\r
240 * description in the description area. Otherwise when the item is not of the expected
\r
241 * type or there is no selection, it empties the description area.
\r
243 private void onTreeSelected() {
\r
244 updateButtonsState();
\r
246 ISelection sel = mTableViewerPackages.getSelection();
\r
247 if (sel instanceof IStructuredSelection) {
\r
248 Object elem = ((IStructuredSelection) sel).getFirstElement();
\r
249 if (elem instanceof IDescription) {
\r
250 mDescriptionLabel.setText(((IDescription) elem).getLongDescription());
\r
251 mDescriptionContainer.layout(true);
\r
255 mDescriptionLabel.setText(""); //$NON-NLS1-$
\r
258 private void onUpdateSelected() {
\r
259 mUpdaterData.updateOrInstallAll(null /*selectedArchives*/);
\r
262 private void onDeleteSelected() {
\r
263 ISelection sel = mTableViewerPackages.getSelection();
\r
264 if (sel instanceof IStructuredSelection) {
\r
265 Object elem = ((IStructuredSelection) sel).getFirstElement();
\r
266 if (elem instanceof Package) {
\r
268 String title = "Delete SDK Package";
\r
269 String error = null;
\r
271 Package p = (Package) elem;
\r
272 Archive[] archives = p.getArchives();
\r
273 if (archives.length == 1 && archives[0] != null && archives[0].isLocal()) {
\r
274 Archive archive = archives[0];
\r
275 String osPath = archive.getLocalOsPath();
\r
277 File dir = new File(osPath);
\r
278 if (dir.isDirectory()) {
\r
279 String msg = String.format("Are you sure you want to delete '%1$s' at '%2$s'? This cannot be undone.",
\r
280 p.getShortDescription(), osPath);
\r
282 if (MessageDialog.openQuestion(getShell(), title, msg)) {
\r
283 archive.deleteLocal();
\r
286 onRefreshSelected();
\r
289 error = "Directory not found for this package";
\r
292 error = "No local archive found for this package";
\r
295 if (error != null) {
\r
296 MessageDialog.openError(getShell(), title, error);
\r
304 private void onRefreshSelected() {
\r
305 mUpdaterData.reloadSdk();
\r
306 updateButtonsState();
\r
309 public void onSdkChange() {
\r
310 LocalSdkAdapter localSdkAdapter = mUpdaterData.getLocalSdkAdapter();
\r
311 mTableViewerPackages.setLabelProvider( localSdkAdapter.getLabelProvider());
\r
312 mTableViewerPackages.setContentProvider(localSdkAdapter.getContentProvider());
\r
313 mTableViewerPackages.setInput(localSdkAdapter);
\r
317 // End of hiding from SWT Designer
\r