0
|
1 |
/*
|
|
2 |
* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
|
|
3 |
* All rights reserved.
|
|
4 |
* This component and the accompanying materials are made available
|
|
5 |
* under the terms of "Eclipse Public License v1.0"
|
|
6 |
* which accompanies this distribution, and is available
|
|
7 |
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
8 |
*
|
|
9 |
* Initial Contributors:
|
|
10 |
* Nokia Corporation - initial contribution.
|
|
11 |
*
|
|
12 |
* Contributors:
|
|
13 |
*
|
|
14 |
* Description:
|
|
15 |
*
|
|
16 |
*/
|
|
17 |
|
|
18 |
|
|
19 |
package com.nokia.s60tools.appdep.ui.views.main;
|
|
20 |
|
|
21 |
import java.io.FileNotFoundException;
|
|
22 |
import java.io.IOException;
|
|
23 |
import java.util.ArrayList;
|
|
24 |
import java.util.NoSuchElementException;
|
|
25 |
|
|
26 |
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
|
27 |
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
|
28 |
|
|
29 |
import com.nokia.s60tools.appdep.core.AppDepSettings;
|
|
30 |
import com.nokia.s60tools.appdep.core.ITargetPlatform;
|
|
31 |
import com.nokia.s60tools.appdep.core.data.CacheDataConstants;
|
|
32 |
import com.nokia.s60tools.appdep.core.data.ComponentLinkLeafNode;
|
|
33 |
import com.nokia.s60tools.appdep.core.data.ComponentNode;
|
|
34 |
import com.nokia.s60tools.appdep.core.data.ComponentParentNode;
|
|
35 |
import com.nokia.s60tools.appdep.core.model.ComponentPropertiesData;
|
|
36 |
import com.nokia.s60tools.appdep.core.model.ExportFunctionData;
|
|
37 |
import com.nokia.s60tools.appdep.core.model.ImportFunctionData;
|
|
38 |
import com.nokia.s60tools.appdep.exceptions.CacheFileDoesNotExistException;
|
|
39 |
import com.nokia.s60tools.appdep.exceptions.CacheIndexNotReadyException;
|
|
40 |
import com.nokia.s60tools.appdep.resources.Messages;
|
|
41 |
import com.nokia.s60tools.sdk.SdkInformation;
|
|
42 |
|
|
43 |
/**
|
|
44 |
* Selection change listener for main view.
|
|
45 |
*/
|
|
46 |
public class MainViewSelectionChangedListener implements
|
|
47 |
ISelectionChangedListener {
|
|
48 |
|
|
49 |
//
|
|
50 |
// Members
|
|
51 |
//
|
|
52 |
private final MainView view;
|
|
53 |
private final ArrayList<ImportFunctionData> importFunctionsArrayList;
|
|
54 |
private final ArrayList<ExportFunctionData> exportFunctionsArrayList;
|
|
55 |
private boolean propertiesFoundSuccessfully;
|
|
56 |
|
|
57 |
/**
|
|
58 |
* Default constructor.
|
|
59 |
* @param view Reference to main view
|
|
60 |
* @param importFunctionsArrayList Import function list to be updated on selection.
|
|
61 |
* @param exportFunctionsArrayList Export function list to be updated on selection.
|
|
62 |
*/
|
|
63 |
public MainViewSelectionChangedListener(MainView view,
|
|
64 |
ArrayList<ImportFunctionData> importFunctionsArrayList,
|
|
65 |
ArrayList<ExportFunctionData> exportFunctionsArrayList){
|
|
66 |
this.view = view;
|
|
67 |
this.importFunctionsArrayList = importFunctionsArrayList;
|
|
68 |
this.exportFunctionsArrayList = exportFunctionsArrayList;
|
|
69 |
}
|
|
70 |
|
|
71 |
/* (non-Javadoc)
|
|
72 |
* @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
|
|
73 |
*/
|
|
74 |
public void selectionChanged(SelectionChangedEvent event) {
|
|
75 |
try {
|
|
76 |
|
|
77 |
Object obj = view.getComponentTreeSelectedElement();
|
|
78 |
|
|
79 |
// By default component properties data reference
|
|
80 |
// is set to null
|
|
81 |
view.setSelectedComponentPropertiesData(null);
|
|
82 |
|
|
83 |
if(obj == null){
|
|
84 |
// We might get null-selections when
|
|
85 |
// tree is expanded/collapsed.
|
|
86 |
return;
|
|
87 |
}
|
|
88 |
else{
|
|
89 |
// Storing the selection for further reference in case
|
|
90 |
// selection is lost because of the user decides
|
|
91 |
// to use 'Go Into' functionality which loses the selection.
|
|
92 |
view.setMostRecentlySelectedComponentNode(obj);
|
|
93 |
}
|
|
94 |
|
|
95 |
// The object is for sure an instance of ComponentNode
|
|
96 |
ComponentNode node = (ComponentNode) obj;
|
|
97 |
// Storing name of the selected component (that might be name of the concrete component replacing generic one).
|
|
98 |
String selectedComponentName = node.getName();
|
|
99 |
// Component node instance which is selected or selected leaf node refers to
|
|
100 |
ComponentParentNode componentNodeInstance;
|
|
101 |
// Storing original component name in here, if we are replacing a generic component
|
|
102 |
String selectedComponentOriginalName;
|
|
103 |
if(node instanceof ComponentParentNode){
|
|
104 |
componentNodeInstance = (ComponentParentNode)node;
|
|
105 |
}
|
|
106 |
else{
|
|
107 |
// We have leaf node
|
|
108 |
ComponentLinkLeafNode leafNode = (ComponentLinkLeafNode)node;
|
|
109 |
// Getting referred component
|
|
110 |
componentNodeInstance = leafNode.getReferredComponent();
|
|
111 |
}
|
|
112 |
// Storing name of the original component if needed
|
|
113 |
if(componentNodeInstance.wasGenericComponent()){
|
|
114 |
selectedComponentOriginalName = componentNodeInstance.getOriginalName();
|
|
115 |
}else{
|
|
116 |
// No concrete component replacement done and therefore selected component is the original one.
|
|
117 |
selectedComponentOriginalName = selectedComponentName;
|
|
118 |
}
|
|
119 |
|
|
120 |
String parentComponentName = node.getParent().getName();
|
|
121 |
|
|
122 |
AppDepSettings st = AppDepSettings.getActiveSettings();
|
|
123 |
SdkInformation sdkInfo = st.getCurrentlyUsedSdk();
|
|
124 |
|
|
125 |
//Updating tool bar text if the view is fully populated
|
|
126 |
// i.e. dependency search is finished.
|
|
127 |
if(!MainView.isDependencySearchOngoing()){
|
|
128 |
String descr = null;
|
|
129 |
if(sdkInfo != null){
|
|
130 |
descr =
|
|
131 |
Messages.getString("MainViewSelectionChangedListener.SDK_Prefix") //$NON-NLS-1$
|
|
132 |
+ sdkInfo.getSdkId()
|
|
133 |
+ " - " //$NON-NLS-1$
|
|
134 |
+ st.getCurrentlyUsedTargetPlatformsAsString()
|
|
135 |
+ " " //$NON-NLS-1$
|
|
136 |
+ st.getBuildType().getBuildTypeDescription()
|
|
137 |
+ Messages.getString("MainViewSelectionChangedListener.Component_Prefix") //$NON-NLS-1$
|
|
138 |
+ node.getFullName();
|
|
139 |
|
|
140 |
view.updateDescription(descr);
|
|
141 |
}
|
|
142 |
}
|
|
143 |
|
|
144 |
// Fetching property information for the selected component
|
|
145 |
//For properties, cannot use selectedComponentName, because it may point to generic component
|
|
146 |
propertiesFoundSuccessfully = updateComponentPropertyInformation(selectedComponentName, st.getCurrentlyAnalyzedComponentTargetPlatform());
|
|
147 |
|
|
148 |
// Clearing old information for imported functions
|
|
149 |
importFunctionsArrayList.clear();
|
|
150 |
// and also for exported ones
|
|
151 |
exportFunctionsArrayList.clear();
|
|
152 |
|
|
153 |
// Is currently used SDK configured?
|
|
154 |
if(sdkInfo != null){
|
|
155 |
// Export functions array list can be populated
|
|
156 |
// if component is not an EXE file, because there
|
|
157 |
// might exist EXE and DLL files with the same name,
|
|
158 |
// and the export function information is only available
|
|
159 |
// for DLLs. If EXE files were passed further, it would
|
|
160 |
// give the information for the DLL with the same name.
|
|
161 |
if(! isExeFile(selectedComponentName)){
|
|
162 |
// For exported functions using always concrete component if available
|
|
163 |
updateExportFunctionsArray(selectedComponentName);
|
|
164 |
}
|
|
165 |
}
|
|
166 |
|
|
167 |
// Checking if root component has been selected
|
|
168 |
ComponentParentNode pNode = null;
|
|
169 |
if(obj instanceof ComponentParentNode){
|
|
170 |
pNode = (ComponentParentNode) obj;
|
|
171 |
if(pNode.isRootComponent()){
|
|
172 |
// Disabling action that are not valid for root component
|
|
173 |
view.disableSetAsNewRootAction();
|
|
174 |
// The showing of parent import functions
|
|
175 |
// is not applicable for the root component
|
|
176 |
// Just refreshing view when old imported
|
|
177 |
// functions information has been cleared.
|
|
178 |
refreshMainView();
|
|
179 |
return;
|
|
180 |
}
|
|
181 |
}
|
|
182 |
else if(obj instanceof ComponentLinkLeafNode){
|
|
183 |
ComponentLinkLeafNode linkNode = (ComponentLinkLeafNode) obj;
|
|
184 |
pNode = linkNode.getReferredComponent();
|
|
185 |
}
|
|
186 |
|
|
187 |
// Also link node can refer to root component
|
|
188 |
if(pNode.isMissing() || pNode.isRootComponent()){
|
|
189 |
view.disableSetAsNewRootAction();
|
|
190 |
view.enableLocateComponentAction();
|
|
191 |
}
|
|
192 |
else{
|
|
193 |
view.enableSetAsNewRootAction();
|
|
194 |
view.disableLocateComponentAction();
|
|
195 |
}
|
|
196 |
|
|
197 |
// Import functions can be fetched selected node is not root component
|
|
198 |
updateImportFunctionsArray(selectedComponentOriginalName, parentComponentName);
|
|
199 |
|
|
200 |
// Checks if there are unresolved import function names and if those can be fetched from export function data
|
|
201 |
checkForUnresolvedImportFunctionNames();
|
|
202 |
|
|
203 |
// Finally asking from main view that content providers gets updated data for showing.
|
|
204 |
refreshMainView();
|
|
205 |
}
|
|
206 |
catch (CacheIndexNotReadyException e) {
|
|
207 |
//
|
|
208 |
// This may happen when no SDK selection has been made and therefore
|
|
209 |
// no cache indexes has been created.
|
|
210 |
// There is only single node in tree view with help text available
|
|
211 |
// for selection that for sure raises this exception.
|
|
212 |
//
|
|
213 |
// => can be ignored safely
|
|
214 |
//
|
|
215 |
}
|
|
216 |
catch (Exception e) {
|
|
217 |
e.printStackTrace();
|
|
218 |
}
|
|
219 |
|
|
220 |
}
|
|
221 |
|
|
222 |
/**
|
|
223 |
* Checks if there are unresolved import function names and if those can be fetched from export function data.
|
|
224 |
* This method does not have any effects if there are no unresolved imported functions, and if there are no
|
|
225 |
* exported function data available.
|
|
226 |
* @precondition if there are unresolved imported function names, there has to be valid exported functions data
|
|
227 |
* available for successful operation.
|
|
228 |
* @postcondition names of unresolved imported function names in <code>importFunctionsArrayList</code> are replaced
|
|
229 |
* by function names got from <code>exportFunctionsArrayList</code>.
|
|
230 |
*/
|
|
231 |
private void checkForUnresolvedImportFunctionNames() {
|
|
232 |
// In case there is no exported data available, there is no use to continue the checking
|
|
233 |
if(exportFunctionsArrayList.size() == 0) return;
|
|
234 |
|
|
235 |
// Otherwise checking imported functions array for unresolved function names
|
|
236 |
for (int i = 0; i < importFunctionsArrayList.size(); i++) {
|
|
237 |
ImportFunctionData importFunc = importFunctionsArrayList.get(i);
|
|
238 |
if(importFunc.getFunctionName().endsWith(CacheDataConstants.FUNC_NAME_NOT_RESOLVED)){
|
|
239 |
String funcName = getFuncNameFromExportedFunctions(importFunc.getFunctionOrdinalAsInt());
|
|
240 |
if(funcName != null){
|
|
241 |
importFunc.setFunctionName(funcName);
|
|
242 |
}
|
|
243 |
}
|
|
244 |
}
|
|
245 |
}
|
|
246 |
|
|
247 |
/**
|
|
248 |
* Gets function name from exported function array list with given ordinal.
|
|
249 |
* @param ordinal function ordinal to get name for.
|
|
250 |
* @return Function name or <code>null</code> if cannot be resolved.
|
|
251 |
*/
|
|
252 |
private String getFuncNameFromExportedFunctions(int ordinal) {
|
|
253 |
// If we have valid ordinal that exists also in exported functions data...
|
|
254 |
if(ordinal > 0 && ordinal <= exportFunctionsArrayList.size()){
|
|
255 |
//...returning the function name for it
|
|
256 |
return exportFunctionsArrayList.get(ordinal-1).getFunctionName();
|
|
257 |
}
|
|
258 |
// Could not found match from exported function data
|
|
259 |
return null;
|
|
260 |
}
|
|
261 |
|
|
262 |
/**
|
|
263 |
* Checks is given file name has EXE extension, or not.
|
|
264 |
* @param fileNameStr File name to be checked for.
|
|
265 |
* @return Returns <code>true</code> if file has EXE extension,
|
|
266 |
* otherwise <code>false</code>.
|
|
267 |
*/
|
|
268 |
private boolean isExeFile(String fileNameStr) {
|
|
269 |
int extIndex = fileNameStr.lastIndexOf("."); //$NON-NLS-1$
|
|
270 |
if(extIndex != -1){
|
|
271 |
String extStr = fileNameStr.substring(extIndex+1, fileNameStr.length());
|
|
272 |
if(extStr.equalsIgnoreCase("EXE")){ //$NON-NLS-1$
|
|
273 |
return true;
|
|
274 |
}
|
|
275 |
}
|
|
276 |
return false;
|
|
277 |
}
|
|
278 |
|
|
279 |
/**
|
|
280 |
* Performs refresh and other operation needed to
|
|
281 |
* run after refresh.
|
|
282 |
*/
|
|
283 |
private void refreshMainView() {
|
|
284 |
view.refresh();
|
|
285 |
if(propertiesFoundSuccessfully){
|
|
286 |
// This resizes value column which enables the seeing
|
|
287 |
// of all the capabilities defined for the component.
|
|
288 |
view.performValueColumnPackToPropertiesTab();
|
|
289 |
}
|
|
290 |
}
|
|
291 |
|
|
292 |
/**
|
|
293 |
* Updates importFunctionsArrayList with information that was found
|
|
294 |
* for the selected component.
|
|
295 |
* @param selectedComponentName Name of the component that has been selected.
|
|
296 |
* @param parentComponentName Parent component of the selected component.
|
|
297 |
* @throws FileNotFoundException
|
|
298 |
* @throws IOException
|
|
299 |
* @throws CacheIndexNotReadyException
|
|
300 |
* @throws CacheFileDoesNotExistException
|
|
301 |
*/
|
|
302 |
private void updateImportFunctionsArray(String selectedComponentName, String parentComponentName) throws FileNotFoundException, IOException, CacheIndexNotReadyException, CacheFileDoesNotExistException {
|
|
303 |
|
|
304 |
importFunctionsArrayList.clear(); // Making sure that array is cleared
|
|
305 |
try {
|
|
306 |
// Non-root component => seeking for the parent imported functions
|
|
307 |
importFunctionsArrayList.addAll(
|
|
308 |
MainViewDataPopulator.getParentImportedFunctionsForComponent(
|
|
309 |
parentComponentName,
|
|
310 |
selectedComponentName)
|
|
311 |
);
|
|
312 |
} catch (Exception e) {
|
|
313 |
// Catching exceptions here, because throwing them upper level would prevent fetching of component properties.
|
|
314 |
e.printStackTrace();
|
|
315 |
}
|
|
316 |
}
|
|
317 |
|
|
318 |
/**
|
|
319 |
* Updates property information for the currently
|
|
320 |
* selected component.
|
|
321 |
* @param selectedComponentName Name of the component that has been selected.
|
|
322 |
* @param targetPlatform Target platform restriction, or <code>null</code> if target platform does not matter.
|
|
323 |
* @return Returns <code>true</code> of component properties was found successfully,
|
|
324 |
* otherwise returns <code>false</code>.
|
|
325 |
* @throws IOException
|
|
326 |
* @throws CacheIndexNotReadyException
|
|
327 |
*/
|
|
328 |
private boolean updateComponentPropertyInformation(String selectedComponentName, ITargetPlatform targetPlatform) throws IOException, CacheIndexNotReadyException {
|
|
329 |
|
|
330 |
boolean propertiesFound = false;
|
|
331 |
|
|
332 |
try {
|
|
333 |
|
|
334 |
ComponentPropertiesData comPropData = MainViewDataPopulator
|
|
335 |
.getComponentPropertyArrayForComponent(selectedComponentName, targetPlatform);
|
|
336 |
propertiesFound = true;
|
|
337 |
view.setSelectedComponentPropertiesData(comPropData);
|
|
338 |
} catch (NoSuchElementException e1) {
|
|
339 |
// This can be ignored because there may be components
|
|
340 |
// that does not exist in cache at all
|
|
341 |
} catch (java.lang.NullPointerException e1) {
|
|
342 |
// This can be ignored because we'll get this if
|
|
343 |
// currently used SDK is not yet configured and we
|
|
344 |
// select the root node that just advices the user
|
|
345 |
// to double-click the root node.
|
|
346 |
} catch (CacheFileDoesNotExistException e2) {
|
|
347 |
// This might happen during dialog to view transitions
|
|
348 |
// When cache file does not exist yet.
|
|
349 |
} catch (Exception e3) {
|
|
350 |
e3.printStackTrace();
|
|
351 |
}
|
|
352 |
return propertiesFound;
|
|
353 |
}
|
|
354 |
|
|
355 |
/**
|
|
356 |
* Updates exportFunctionsArrayList with information that was found
|
|
357 |
* for the selected component.
|
|
358 |
* @param selectedComponentName Name of the component that has been selected.
|
|
359 |
* @throws FileNotFoundException
|
|
360 |
* @throws IOException
|
|
361 |
* @throws CacheIndexNotReadyException
|
|
362 |
* @throws CacheFileDoesNotExistException
|
|
363 |
*/
|
|
364 |
private void updateExportFunctionsArray(String selectedComponentName) throws FileNotFoundException, IOException, CacheIndexNotReadyException, CacheFileDoesNotExistException {
|
|
365 |
|
|
366 |
try {
|
|
367 |
exportFunctionsArrayList.clear(); // Making sure that earlier results are destroyed
|
|
368 |
// Populating with new data
|
|
369 |
exportFunctionsArrayList.addAll(MainViewDataPopulator.getExportedFunctionsForComponent(selectedComponentName));
|
|
370 |
|
|
371 |
} catch (NoSuchElementException e) {
|
|
372 |
// The selected component does necessary
|
|
373 |
// have any data about exported functions.
|
|
374 |
// Therefore we can ignore this exception
|
|
375 |
} catch (Exception e) {
|
|
376 |
e.printStackTrace();
|
|
377 |
}
|
|
378 |
}
|
|
379 |
|
|
380 |
}
|