Community
Participate
Working Groups
WizardResourceImportPage's contructor does not attempt to find a common IContainer amongst multiple selected resources. Eclipse: 3.2M4 Plugin: org.eclipse.ui.ide Class: org\eclipse\ui\dialogs\WizardResourceImportPage.java Here is the REVISED constructor, and a new method, getCommonIResource(), for your consideration: //// CODE - START /** * Creates an import wizard page. If the initial resource selection * contains exactly one container resource then it will be used as the default * import destination. Otherwise, if the initial resource selection consists of many resources, * a common container resource will be determined and used as * the default import destination. * * @param name the name of the page * @param selection the current resource selection */ protected WizardResourceImportPage(String name, IStructuredSelection selection) { super(name); //Initialize to null currentResourceSelection = null; if (selection.size() > 0){ if (selection.size() == 1) { Object firstElement = selection.getFirstElement(); if (firstElement instanceof IAdaptable) { Object resource = ((IAdaptable) firstElement) .getAdapter(IResource.class); if (resource != null) currentResourceSelection = (IResource) resource; } if (currentResourceSelection != null) { if (currentResourceSelection.getType() == IResource.FILE) currentResourceSelection = currentResourceSelection.getParent(); if (!currentResourceSelection.isAccessible()) currentResourceSelection = null; } } else { //selection.size() > 1 //attempt to find a common IContainer among all selected resources. Otherwise //return null currentResourceSelection = getCommonIResource(selection); if (currentResourceSelection != null) { if (!currentResourceSelection.isAccessible()) currentResourceSelection = null; }//if } }//if } /** * * This method will attempt to return an IContainer common to all selected resources. * If there is no common IContainer, it will return a null * * @param selection the current resource selection */ protected IResource getCommonIResource(IStructuredSelection selection) { IResource commonIResource = null; IResource someIResource = null; ArrayList resources = new ArrayList(); Object selected = null; Object resource = null; boolean resourcesResideInSameProject = false; Hashtable uniqueProjects = new Hashtable(); String projectName = null; if ( (selection != null) && (selection.size() > 1) ) { try { //First, get the IResource for this selection; if it exists //Second, if the IResource is an IFile, get its container instead //Third, determine if these IResources have a common project Iterator it = selection.iterator(); while(it.hasNext()) { selected = it.next(); if (selected instanceof IAdaptable) { resource = ((IAdaptable) selected).getAdapter(IResource.class); if (resource != null) { someIResource = (IResource) resource; if (someIResource.getType() == IResource.FILE){ resources.add(someIResource.getParent()); }//if else { resources.add(someIResource); }//endif //keep track of unique project names projectName = someIResource.getProject().getName(); if (!uniqueProjects.containsKey( projectName )) { uniqueProjects.put(projectName, projectName); }//if }//if }//if }//while if (resources.size() > 1) { // //figure out if resources all reside in same project // resourcesResideInSameProject = (uniqueProjects.size() == 1); uniqueProjects.clear(); if (!resourcesResideInSameProject) { //resources do reside in the same project, therefore no common IContainer resource is possible //so return null commonIResource = null; }//if else { //all the resources reside in the same project //now find the longest common path IResource[] theResources = (IResource[])resources.toArray(new IResource[0]); resources.clear(); int i = 0; int j =0; IPath currentPath = null; boolean pathSame = true; int iSmallestSegmentCount = -1; int segmentCount = 0; // //trim the IResource paths to the smallest segment size before the main comparison starts // // // if the resources already have the same segment count then the following code won't affect // the resource array elements at all. However, if the segment counts are not identical, then // this step is necessary. iSmallestSegmentCount = Integer.MAX_VALUE; //determine the smallest path segment count among all resources for(i=0;i<theResources.length;i++){ segmentCount = theResources[i].getFullPath().segmentCount(); if (segmentCount < iSmallestSegmentCount) { iSmallestSegmentCount = segmentCount; }//if }//for //reduce all resources to the smallest segment size for(i=0;i<theResources.length;i++){ segmentCount = theResources[i].getFullPath().segmentCount(); if (segmentCount > iSmallestSegmentCount) { for(j=0;j<(segmentCount-iSmallestSegmentCount);j++){ //modifying array of resources to get parent of this //resource and store it in the old position of the child resource theResources[i] = theResources[i].getParent(); }//for }//if }//for // // Begin main comparison loop // boolean commonContainerPathAchieved = false; while(!commonContainerPathAchieved) { // // path segment counts are all the same at this point for all the resources // //get the path of the first element to use for comparison currentPath = theResources[0].getFullPath(); //determine if the resources' paths are the same pathSame = true; for(i=0;i<theResources.length;i++){ if (!currentPath.equals(theResources[i].getFullPath())) { pathSame = false; break; }//if }//for if (pathSame == false) { // // get the parents of all the resources and store them in resource array // for(i=0;i<theResources.length;i++){ //modifying array of resources to get parent of this //resource and store it in the old position of the child resource theResources[i] = theResources[i].getParent(); }//for }//if else { //path is finally common across all resources //break out of loop commonContainerPathAchieved = true; }//endif }//while // // At this point, all the IContainer elements in the array have the same path // //set the commonIResource commonIResource = theResources[0]; }//endif }//if }//try catch(Exception e){ e.printStackTrace(); }//catch }//if return commonIResource; } //// CODE - END
Created attachment 33966 [details] Patch for org\eclipse\ui\dialogs\WizardResourceImportPage.java
Could you provide a description of the problem?
Currently the import wizard will only populate the "Into folder" field if 1 resource is pre-selected by the user in a view. (The logic for this lies in the WizardResourceImportPage constructor). For a logical element (which uses the new ResourceMapping concept), it is possible for it to be mapped to 1-to-N resources. Having said that, what currently happens is when the user selects 1 logical element that has several resources backing it, the WizardResourceImportPage receives a structured selection of size > 1 and the current code sets currentResourceSelection to null (basically ignores this selection), and the "Into folder" field stays blank. The WizardResourceImportPage should really try to determine a container common to all selected resources. Example : If 2 resources from 1 logical element sit in the same project, then that project should be the common container, and it should show up in the "Into folder". If none can be found (as in the case where 2 logical elements are selected from DIFFERENT projects), only then set currentResourceSelection to null, and cause the "Into folder" field to stay blank.
Copying Tod, as he has done some of the logical resource changes in the UI.
I am giving this bug to Tod as he is working on the logical->physical resources problem.
Hi Tod, We were hoping this fix could make it in mid-Feburary. Is this possible? Please advise. Thank you. :)
As this is an API change it is pretty late in the game to get this in (API freeze is in 3 hours). Do you need that method to be protected? If it can be private we have more flexibility.
In WizardResourceImportPage, you can make the method private: as show below: private IResource getCommonIResource(IStructuredSelection selection) { That's fine with me. Thanks. :)
Why is it you want this behavioural change BTW. We generally do not try to find common parents for something like this as it is so easy to select something that is not what the user wanted. If they have a single selection they are clear.
Hi, Our reasons are listed in Comment #3. But to re-iterate briefly... We want the import wizard activated off our logical view to behave the "same" as when activated off the navigator view (non-logical view). If our single logical element has 2 resources backing it (the user can only see the single logical element), and the user has it selected before right-clicking and selecting Import..., the user should see the project name of those 2 backing resources in the Into folder; JUST LIKE the user would see the project name of a single resource appear in the Into Folder field of the Import wizard if 1 single file was selected before the wizard was chosen.
Prakash is now responsible for watching bugs in the [Wizards] component area.
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.