1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.eclipse.org/org/documents/epl-v10.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.ide.eclipse.adt.internal.properties;
18
19import com.android.SdkConstants;
20import com.android.ide.eclipse.adt.AdtPlugin;
21import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
22import com.android.ide.eclipse.adt.internal.sdk.Sdk;
23import com.android.sdklib.IAndroidTarget;
24import com.android.sdklib.internal.project.ProjectProperties;
25import com.android.sdklib.internal.project.ProjectPropertiesWorkingCopy;
26import com.android.sdkuilib.internal.widgets.SdkTargetSelector;
27
28import org.eclipse.core.resources.IProject;
29import org.eclipse.core.resources.IResource;
30import org.eclipse.core.runtime.NullProgressMonitor;
31import org.eclipse.swt.SWT;
32import org.eclipse.swt.events.SelectionAdapter;
33import org.eclipse.swt.events.SelectionEvent;
34import org.eclipse.swt.layout.GridData;
35import org.eclipse.swt.layout.GridLayout;
36import org.eclipse.swt.widgets.Button;
37import org.eclipse.swt.widgets.Composite;
38import org.eclipse.swt.widgets.Control;
39import org.eclipse.swt.widgets.Group;
40import org.eclipse.ui.dialogs.PropertyPage;
41
42/**
43 * Property page for "Android" project.
44 * This is accessible from the Package Explorer when right clicking a project and choosing
45 * "Properties".
46 *
47 */
48public class AndroidPropertyPage extends PropertyPage {
49
50    private IProject mProject;
51    private SdkTargetSelector mSelector;
52    private Button mIsLibrary;
53    // APK-SPLIT: This is not yet supported, so we hide the UI
54//    private Button mSplitByDensity;
55    private LibraryProperties mLibraryDependencies;
56    private ProjectPropertiesWorkingCopy mPropertiesWorkingCopy;
57
58    public AndroidPropertyPage() {
59        // pass
60    }
61
62    @Override
63    protected Control createContents(Composite parent) {
64        // get the element (this is not yet valid in the constructor).
65        mProject = (IProject)getElement();
66
67        // get the targets from the sdk
68        IAndroidTarget[] targets = null;
69        if (Sdk.getCurrent() != null) {
70            targets = Sdk.getCurrent().getTargets();
71        }
72
73        // build the UI.
74        Composite top = new Composite(parent, SWT.NONE);
75        top.setLayoutData(new GridData(GridData.FILL_BOTH));
76        top.setLayout(new GridLayout(1, false));
77
78        Group targetGroup = new Group(top, SWT.NONE);
79        targetGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
80        targetGroup.setLayout(new GridLayout(1, false));
81        targetGroup.setText("Project Build Target");
82
83        mSelector = new SdkTargetSelector(targetGroup, targets);
84
85        Group libraryGroup = new Group(top, SWT.NONE);
86        libraryGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
87        libraryGroup.setLayout(new GridLayout(1, false));
88        libraryGroup.setText("Library");
89
90        mIsLibrary = new Button(libraryGroup, SWT.CHECK);
91        mIsLibrary.setText("Is Library");
92
93        mLibraryDependencies = new LibraryProperties(libraryGroup);
94
95        // fill the ui
96        fillUi();
97
98        // add callbacks
99        mSelector.setSelectionListener(new SelectionAdapter() {
100            @Override
101            public void widgetSelected(SelectionEvent e) {
102                updateValidity();
103            }
104        });
105
106        if (mProject.isOpen() == false) {
107            // disable the ui.
108        }
109
110        return top;
111    }
112
113    @Override
114    public boolean performOk() {
115        Sdk currentSdk = Sdk.getCurrent();
116        if (currentSdk != null && mProject.isOpen()) {
117            ProjectState state = Sdk.getProjectState(mProject);
118
119            // simply update the properties copy. Eclipse will be notified of the file change
120            // and will reload it smartly (detecting differences) and updating the ProjectState.
121            // See Sdk.mFileListener
122            boolean mustSaveProp = false;
123
124            IAndroidTarget newTarget = mSelector.getSelected();
125            if (state == null || newTarget != state.getTarget()) {
126                mPropertiesWorkingCopy.setProperty(ProjectProperties.PROPERTY_TARGET,
127                        newTarget.hashString());
128                mustSaveProp = true;
129            }
130
131            if (state == null || mIsLibrary.getSelection() != state.isLibrary()) {
132                mPropertiesWorkingCopy.setProperty(ProjectProperties.PROPERTY_LIBRARY,
133                        Boolean.toString(mIsLibrary.getSelection()));
134                mustSaveProp = true;
135            }
136
137            if (mLibraryDependencies.save()) {
138                mustSaveProp = true;
139            }
140
141            if (mustSaveProp) {
142                try {
143                    mPropertiesWorkingCopy.save();
144
145                    IResource projectProp = mProject.findMember(SdkConstants.FN_PROJECT_PROPERTIES);
146                    if (projectProp != null) {
147                        projectProp.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
148                    }
149                } catch (Exception e) {
150                    String msg = String.format(
151                            "Failed to save %1$s for project %2$s",
152                            SdkConstants.FN_PROJECT_PROPERTIES, mProject.getName());
153                    AdtPlugin.log(e, msg);
154                }
155            }
156        }
157
158        return true;
159    }
160
161    @Override
162    protected void performDefaults() {
163        fillUi();
164        updateValidity();
165    }
166
167    private void fillUi() {
168        if (Sdk.getCurrent() != null && mProject.isOpen()) {
169            ProjectState state = Sdk.getProjectState(mProject);
170
171            // make a working copy of the properties
172            mPropertiesWorkingCopy = state.getProperties().makeWorkingCopy();
173
174            // get the target
175            IAndroidTarget target = state.getTarget();
176            if (target != null) {
177                mSelector.setSelection(target);
178            }
179
180            mIsLibrary.setSelection(state.isLibrary());
181            mLibraryDependencies.setContent(state, mPropertiesWorkingCopy);
182        }
183
184    }
185
186    private void updateValidity() {
187        // look for the selection and validate the page if there is a selection
188        IAndroidTarget target = mSelector.getSelected();
189        setValid(target != null);
190    }
191}
192