OSDN Git Service

android-2.1_r1 snapshot
[android-x86/sdk.git] / sdkmanager / libs / sdkuilib / src / com / android / sdkuilib / internal / repository / LocalPackagesPage.java
1 /*\r
2  * Copyright (C) 2009 The Android Open Source Project\r
3  *\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
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\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
15  */\r
16 \r
17 package com.android.sdkuilib.internal.repository;\r
18 \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
23 \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
43 \r
44 import java.io.File;\r
45 \r
46 /*\r
47  * TODO list\r
48  * - select => update desc, enable update + delete, enable home page if url\r
49  * - home page callback\r
50  * - update callback\r
51  * - delete callback\r
52  * - refresh callback\r
53  */\r
54 \r
55 public class LocalPackagesPage extends Composite implements ISdkListener {\r
56 \r
57     private final UpdaterData mUpdaterData;\r
58 \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
73 \r
74 \r
75     /**\r
76      * Create the composite.\r
77      * @param parent The parent of the composite.\r
78      * @param updaterData An instance of {@link UpdaterData}.\r
79      */\r
80     public LocalPackagesPage(Composite parent, UpdaterData updaterData) {\r
81         super(parent, SWT.BORDER);\r
82 \r
83         mUpdaterData = updaterData;\r
84 \r
85         createContents(this);\r
86         postCreate();  //$hide$\r
87     }\r
88 \r
89     private void createContents(Composite parent) {\r
90         parent.setLayout(new GridLayout(3, false));\r
91 \r
92         createSdkLocation(parent);\r
93 \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
99             @Override\r
100             public void widgetSelected(SelectionEvent e) {\r
101                 onTreeSelected(); //$hide$\r
102             }\r
103         });\r
104 \r
105         mColumnPackages = new TableColumn(mTablePackages, SWT.NONE);\r
106         mColumnPackages.setWidth(377);\r
107         mColumnPackages.setText("Installed Packages");\r
108 \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
113 \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
117 \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
121 \r
122         mUpdateButton = new Button(mContainerButtons, SWT.NONE);\r
123         mUpdateButton.setText("Update All...");\r
124         mUpdateButton.addSelectionListener(new SelectionAdapter() {\r
125             @Override\r
126             public void widgetSelected(SelectionEvent e) {\r
127                 onUpdateSelected();  //$hide$ (hide from SWT designer)\r
128             }\r
129         });\r
130 \r
131         mPlaceholder1 = new Label(mContainerButtons, SWT.NONE);\r
132         mPlaceholder1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));\r
133 \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
138             @Override\r
139             public void widgetSelected(SelectionEvent e) {\r
140                 onDeleteSelected();  //$hide$ (hide from SWT designer)\r
141             }\r
142         });\r
143 \r
144         mPlaceholder2 = new Label(mContainerButtons, SWT.NONE);\r
145         mPlaceholder2.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));\r
146 \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
151             @Override\r
152             public void widgetSelected(SelectionEvent e) {\r
153                 onRefreshSelected();  //$hide$ (hide from SWT designer)\r
154             }\r
155         });\r
156     }\r
157 \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
162 \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
165 \r
166         mSdkLocText = new Text(parent, SWT.BORDER);\r
167         mSdkLocText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));\r
168 \r
169         if (mUpdaterData.canUserChangeSdkRoot()) {\r
170             mSdkLocBrowse = new Button(parent, SWT.NONE);\r
171             mSdkLocBrowse.setText("Browse...");\r
172         } else {\r
173             mSdkLocText.setEditable(false);\r
174             ((GridData)mSdkLocText.getLayoutData()).horizontalSpan++;\r
175         }\r
176 \r
177         if (mUpdaterData.getOsSdkRoot() != null) {\r
178             mSdkLocText.setText(mUpdaterData.getOsSdkRoot());\r
179         }\r
180     }\r
181 \r
182     @Override\r
183     public void dispose() {\r
184         mUpdaterData.removeListener(this);\r
185         super.dispose();\r
186     }\r
187 \r
188     @Override\r
189     protected void checkSubclass() {\r
190         // Disable the check that prevents subclassing of SWT components\r
191     }\r
192 \r
193     // -- Start of internal part ----------\r
194     // Hide everything down-below from SWT designer\r
195     //$hide>>$\r
196 \r
197     /**\r
198      * Called by the constructor right after {@link #createContents(Composite)}.\r
199      */\r
200     private void postCreate() {\r
201         mUpdaterData.addListeners(this);\r
202         adjustColumnsWidth();\r
203         updateButtonsState();\r
204     }\r
205 \r
206     /**\r
207      * Adds a listener to adjust the columns width when the parent is resized.\r
208      * <p/>\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
211      */\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
215             @Override\r
216             public void controlResized(ControlEvent e) {\r
217                 Rectangle r = mTablePackages.getClientArea();\r
218                 mColumnPackages.setWidth(r.width);\r
219             }\r
220         };\r
221         mTablePackages.addControlListener(resizer);\r
222         resizer.controlResized(null);\r
223     }\r
224 \r
225     /**\r
226      * Enable or disable buttons depending on list content and selection\r
227      */\r
228     private void updateButtonsState() {\r
229         ISelection sel = mTableViewerPackages.getSelection();\r
230         boolean hasSelection = sel != null && !sel.isEmpty();\r
231 \r
232         mUpdateButton.setEnabled(mTablePackages.getItemCount() > 0);\r
233         mDeleteButton.setEnabled(hasSelection);\r
234         mRefreshButton.setEnabled(true);\r
235     }\r
236 \r
237     /**\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
242      */\r
243     private void onTreeSelected() {\r
244         updateButtonsState();\r
245 \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
252                 return;\r
253             }\r
254         }\r
255         mDescriptionLabel.setText("");  //$NON-NLS1-$\r
256     }\r
257 \r
258     private void onUpdateSelected() {\r
259         mUpdaterData.updateOrInstallAll(null /*selectedArchives*/);\r
260     }\r
261 \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
267 \r
268                 String title = "Delete SDK Package";\r
269                 String error = null;\r
270 \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
276 \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
281 \r
282                         if (MessageDialog.openQuestion(getShell(), title, msg)) {\r
283                             archive.deleteLocal();\r
284 \r
285                             // refresh list\r
286                             onRefreshSelected();\r
287                         }\r
288                     } else {\r
289                         error = "Directory not found for this package";\r
290                     }\r
291                 } else {\r
292                     error = "No local archive found for this package";\r
293                 }\r
294 \r
295                 if (error != null) {\r
296                     MessageDialog.openError(getShell(), title, error);\r
297                 }\r
298 \r
299                 return;\r
300             }\r
301         }\r
302     }\r
303 \r
304     private void onRefreshSelected() {\r
305         mUpdaterData.reloadSdk();\r
306         updateButtonsState();\r
307     }\r
308 \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
314         onTreeSelected();\r
315     }\r
316 \r
317     // End of hiding from SWT Designer\r
318     //$hide<<$\r
319 }\r