Java Source Code: org.eclipse.search.internal.ui.SearchDialog


   1: /*******************************************************************************
   2:  * Copyright (c) 2000, 2006 IBM Corporation and others.
   3:  * All rights reserved. This program and the accompanying materials
   4:  * are made available under the terms of the Eclipse Public License v1.0
   5:  * which accompanies this distribution, and is available at
   6:  * http://www.eclipse.org/legal/epl-v10.html
   7:  *
   8:  * Contributors:
   9:  *     IBM Corporation - initial API and implementation
  10:  *     Michael Fraenkel (fraenkel@us.ibm.com) - contributed a fix for:
  11:  *       o Search dialog not respecting activity enablement
  12:  *         (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=45729)
  13:  *******************************************************************************/
  14: package org.eclipse.search.internal.ui;
  15: 
  16: import java.util.ArrayList;
  17: import java.util.HashSet;
  18: import java.util.Iterator;
  19: import java.util.List;
  20: 
  21: import org.eclipse.core.runtime.CoreException;
  22: import org.eclipse.core.runtime.IAdaptable;
  23: import org.eclipse.core.runtime.ISafeRunnable;
  24: import org.eclipse.core.runtime.ListenerList;
  25: import org.eclipse.core.runtime.SafeRunner;
  26: 
  27: import org.eclipse.core.resources.IProject;
  28: import org.eclipse.core.resources.IResource;
  29: import org.eclipse.core.resources.ResourcesPlugin;
  30: 
  31: import org.eclipse.swt.SWT;
  32: import org.eclipse.swt.custom.BusyIndicator;
  33: import org.eclipse.swt.events.DisposeEvent;
  34: import org.eclipse.swt.events.DisposeListener;
  35: import org.eclipse.swt.events.SelectionAdapter;
  36: import org.eclipse.swt.events.SelectionEvent;
  37: import org.eclipse.swt.events.SelectionListener;
  38: import org.eclipse.swt.graphics.Image;
  39: import org.eclipse.swt.graphics.Point;
  40: import org.eclipse.swt.graphics.Rectangle;
  41: import org.eclipse.swt.layout.GridData;
  42: import org.eclipse.swt.layout.GridLayout;
  43: import org.eclipse.swt.widgets.Button;
  44: import org.eclipse.swt.widgets.Composite;
  45: import org.eclipse.swt.widgets.Control;
  46: import org.eclipse.swt.widgets.Display;
  47: import org.eclipse.swt.widgets.Label;
  48: import org.eclipse.swt.widgets.Layout;
  49: import org.eclipse.swt.widgets.Shell;
  50: import org.eclipse.swt.widgets.TabFolder;
  51: import org.eclipse.swt.widgets.TabItem;
  52: 
  53: import org.eclipse.jface.action.LegacyActionTools;
  54: import org.eclipse.jface.dialogs.IDialogConstants;
  55: import org.eclipse.jface.dialogs.IDialogSettings;
  56: import org.eclipse.jface.dialogs.IPageChangeProvider;
  57: import org.eclipse.jface.dialogs.IPageChangedListener;
  58: import org.eclipse.jface.dialogs.PageChangedEvent;
  59: import org.eclipse.jface.operation.IRunnableContext;
  60: import org.eclipse.jface.resource.ImageDescriptor;
  61: import org.eclipse.jface.util.SafeRunnable;
  62: import org.eclipse.jface.viewers.ArrayContentProvider;
  63: import org.eclipse.jface.viewers.CheckStateChangedEvent;
  64: import org.eclipse.jface.viewers.CheckboxTableViewer;
  65: import org.eclipse.jface.viewers.ICheckStateListener;
  66: import org.eclipse.jface.viewers.ILabelProvider;
  67: import org.eclipse.jface.viewers.ISelection;
  68: import org.eclipse.jface.viewers.IStructuredSelection;
  69: import org.eclipse.jface.viewers.LabelProvider;
  70: import org.eclipse.jface.window.Window;
  71: 
  72: import org.eclipse.ui.IEditorPart;
  73: import org.eclipse.ui.IWorkbenchPage;
  74: import org.eclipse.ui.IWorkbenchWindow;
  75: import org.eclipse.ui.IWorkingSet;
  76: import org.eclipse.ui.PlatformUI;
  77: import org.eclipse.ui.activities.WorkbenchActivityHelper;
  78: import org.eclipse.ui.dialogs.ListSelectionDialog;
  79: 
  80: import org.eclipse.search.ui.IReplacePage;
  81: import org.eclipse.search.ui.ISearchPage;
  82: import org.eclipse.search.ui.ISearchPageContainer;
  83: import org.eclipse.search.ui.ISearchPageScoreComputer;
  84: 
  85: import org.eclipse.search.internal.ui.util.ExceptionHandler;
  86: import org.eclipse.search.internal.ui.util.ExtendedDialogWindow;
  87: 
  88:	  public class SearchDialog extends ExtendedDialogWindow implements ISearchPageContainer, IPageChangeProvider {
  89:
  90:	      private class TabFolderLayout extends Layout {
  91:	          protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
  92:            if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT)
  93:                return new Point(wHint, hHint);
  94:
  95:            int x= 0; 
  96:            int y= 0;                
  97:            Control[] children= composite.getChildren();
  98:	              for (int i= 0; i < children.length; i++) {
  99:                Point size= children[i].computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
 100:                x= Math.max(x, size.x);
 101:                y= Math.max(y, size.y);
 102:            }
 103:            
 104:            Point minSize= getMinSize();
 105:            x= Math.max(x, minSize.x);
 106:            y= Math.max(y, minSize.y);
 107:            
 108:            if (wHint != SWT.DEFAULT)
 109:                x= wHint;
 110:            if (hHint != SWT.DEFAULT)
 111:                y= hHint;
 112:            return new Point(x, y);        
 113:        }
 114:	          protected void layout(Composite composite, boolean flushCache) {
 115:            Rectangle rect= composite.getClientArea();
 116:            
 117:            Control[] children= composite.getChildren();
 118:	              for (int i= 0; i < children.length; i++) {
 119:                children[i].setBounds(rect);
 120:            }
 121:        }
 122:    }
 123:    
 124:    
 125:    private static final int SEARCH_ID= IDialogConstants.CLIENT_ID + 1;
 126:    private static final int REPLACE_ID= SEARCH_ID + 1;
 127:    private static final int CUSTOMIZE_ID= REPLACE_ID + 1;
 128:    
 129:    private ISearchPage fCurrentPage;
 130:    private String fInitialPageId;
 131:    private int fCurrentIndex;
 132:
 133:    private List fDescriptors;
 134:    private Point fMinSize;
 135:    private ScopePart[] fScopeParts;
 136:    private boolean fLastEnableState;
 137:    private Button fCustomizeButton;
 138:    private Button fReplaceButton;
 139:    private ListenerList fPageChangeListeners;
 140:    
 141:    private final IWorkbenchWindow fWorkbenchWindow;
 142:    private final ISelection fCurrentSelection;
 143:    private final String[] fCurrentEnclosingProject;
 144:
 145:
 146:	      public SearchDialog(IWorkbenchWindow window, String pageId) {
 147:        super(window.getShell());
 148:        fWorkbenchWindow= window;
 149:        fCurrentSelection= window.getSelectionService().getSelection();
 150:        fCurrentEnclosingProject= evaluateEnclosingProject(fCurrentSelection, getActiveEditor());
 151:
 152:        fDescriptors= filterByActivities(SearchPlugin.getDefault().getEnabledSearchPageDescriptors(pageId));
 153:        fInitialPageId= pageId;
 154:        fPageChangeListeners= null;
 155:        setUseEmbeddedProgressMonitorPart(false);
 156:    }
 157:
 158:	      public static String evaluateEnclosingProject(IAdaptable adaptable) {        
 159:        IProject project= (IProject) adaptable.getAdapter(IProject.class);
 160:	          if (project == null) {
 161:            IResource resource= (IResource) adaptable.getAdapter(IResource.class);
 162:	              if (resource != null) {
 163:                project= resource.getProject();
 164:            }
 165:        }
 166:	          if (project != null && project.isAccessible()) {
 167:            return project.getName();
 168:        }
 169:        return null;
 170:    }
 171:    
 172:	      public static String[] evaluateEnclosingProject(ISelection selection, IEditorPart activeEditor) {
 173:        // always use the editor if active 
 174:	          if (activeEditor != null) {
 175:            String name= evaluateEnclosingProject(activeEditor.getEditorInput());
 176:	              if (name != null) {
 177:                return new String[] { name };
 178:            }
 179:        } else if (selection instanceof IStructuredSelection) {
 180:            HashSet res= new HashSet();
 181:	              for (Iterator iter= ((IStructuredSelection) selection).iterator(); iter.hasNext();) {
 182:                Object curr= iter.next();
 183:	                  if (curr instanceof IWorkingSet) {
 184:                    IWorkingSet workingSet= (IWorkingSet) curr;
 185:	                      if (workingSet.isAggregateWorkingSet() && workingSet.isEmpty()) {
 186:                        IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects();
 187:	                          for (int i= 0; i < projects.length; i++) {
 188:                            IProject proj= projects[i];
 189:	                              if (proj.isOpen()) {
 190:                                res.add(proj.getName());
 191:                            }
 192:                        }
 193:                    } else {
 194:                        IAdaptable[] elements= workingSet.getElements();
 195:	                          for (int i= 0; i < elements.length; i++) {
 196:                            String name= evaluateEnclosingProject(elements[i]);
 197:	                              if (name != null) {
 198:                                res.add(name);
 199:                            }
 200:                        }
 201:                    }
 202:                } else if (curr instanceof IAdaptable) {
 203:                    String name= evaluateEnclosingProject((IAdaptable) curr);
 204:	                      if (name != null) {
 205:                        res.add(name);
 206:                    }
 207:                }
 208:            }
 209:	              if (!res.isEmpty()) {
 210:                return (String[]) res.toArray(new String[res.size()]);
 211:            }
 212:        }
 213:        return new String[0];
 214:    }
 215:
 216:    /* (non-Javadoc)
 217:     * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings()
 218:     */
 219:	      protected IDialogSettings getDialogBoundsSettings() {
 220:        return SearchPlugin.getDefault().getDialogSettingsSection("DialogBounds_SearchDialog"); //$NON-NLS-1$
 221:    }
 222:    
 223:    /* (non-Javadoc)
 224:     * Method declared in Window.
 225:     */
 226:	      protected void configureShell(Shell shell) {
 227:        super.configureShell(shell);
 228:        shell.setText(SearchMessages.SearchDialog_title); 
 229:        PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, ISearchHelpContextIds.SEARCH_DIALOG);
 230:    }
 231:
 232:	      public IWorkbenchWindow getWorkbenchWindow() {
 233:        return fWorkbenchWindow;
 234:    }
 235:    
 236:	      public ISelection getSelection() {
 237:        return fCurrentSelection;
 238:    }
 239:    
 240:	      private IEditorPart getActiveEditor() {
 241:        IWorkbenchPage activePage= fWorkbenchWindow.getActivePage();
 242:	          if (activePage != null) {
 243:            IEditorPart activeEditor= activePage.getActiveEditor();
 244:            if (activeEditor == activePage.getActivePart())
 245:                return activeEditor;
 246:        }
 247:        return null;
 248:    }
 249:    
 250:    //---- Page Handling -------------------------------------------------------
 251:
 252:    /*
 253:     * Overrides method from Window
 254:     */
 255:	      public void create() {
 256:        super.create();
 257:	          if (fCurrentPage != null) {
 258:            fCurrentPage.setVisible(true);
 259:        }
 260:    }
 261:
 262:	      private void handleCustomizePressed() {
 263:        List input= SearchPlugin.getDefault().getSearchPageDescriptors();
 264:        input= filterByActivities(input);
 265:
 266:        final ArrayList createdImages= new ArrayList(input.size());
 267:	          ILabelProvider labelProvider= new LabelProvider() {
 268:	              public String getText(Object element) {
 269:                if (element instanceof SearchPageDescriptor)
 270:                    return LegacyActionTools.removeMnemonics(((SearchPageDescriptor)element).getLabel());
 271:                return null;
 272:            }
 273:	              public Image getImage(Object element) {
 274:	                  if (element instanceof SearchPageDescriptor) {
 275:                    ImageDescriptor imageDesc= ((SearchPageDescriptor)element).getImage();
 276:                    if (imageDesc == null)
 277:                        return null;
 278:                    Image image= imageDesc.createImage();
 279:                    if (image != null)
 280:                        createdImages.add(image);
 281:                    return image;
 282:                }
 283:                return null;
 284:            }
 285:        };
 286:
 287:        String message= SearchMessages.SearchPageSelectionDialog_message; 
 288:        
 289:	          ListSelectionDialog dialog= new ListSelectionDialog(getShell(), input, new ArrayContentProvider(), labelProvider, message) {
 290:	              public void create() {
 291:                super.create();
 292:                final CheckboxTableViewer viewer= getViewer();
 293:                final Button okButton= this.getOkButton();
 294:	                  viewer.addCheckStateListener(new ICheckStateListener() {
 295:	                      public void checkStateChanged(CheckStateChangedEvent event) {
 296:                        okButton.setEnabled(viewer.getCheckedElements().length > 0);
 297:                    }
 298:                });
 299:	                  SelectionListener listener = new SelectionAdapter() {
 300:	                      public void widgetSelected(SelectionEvent e) {
 301:                        okButton.setEnabled(viewer.getCheckedElements().length > 0);
 302:                    }
 303:                };
 304:                this.getButton(IDialogConstants.SELECT_ALL_ID).addSelectionListener(listener);
 305:                this.getButton(IDialogConstants.DESELECT_ALL_ID).addSelectionListener(listener);
 306:            }
 307:        };
 308:        dialog.setTitle(SearchMessages.SearchPageSelectionDialog_title); 
 309:        dialog.setInitialSelections(SearchPlugin.getDefault().getEnabledSearchPageDescriptors(fInitialPageId).toArray());
 310:	          if (dialog.open() == Window.OK) {
 311:            SearchPageDescriptor.setEnabled(dialog.getResult());
 312:            Display display= getShell().getDisplay();
 313:            close();            
 314:	              if (display != null && !display.isDisposed()) {
 315:                display.asyncExec(
 316:	                          new Runnable() {
 317:	                              public void run() {
 318:                                new OpenSearchDialogAction().run();
 319:                            }
 320:                        });
 321:            }
 322:        }
 323:        destroyImages(createdImages);        
 324:    }
 325:
 326:	      private List filterByActivities(List input) {
 327:        ArrayList filteredList= new ArrayList(input.size());
 328:	          for (Iterator descriptors= input.iterator(); descriptors.hasNext();) {
 329:            SearchPageDescriptor descriptor= (SearchPageDescriptor) descriptors.next();
 330:            if (!WorkbenchActivityHelper.filterItem(descriptor))
 331:                filteredList.add(descriptor);
 332:            
 333:        }
 334:        return filteredList;
 335:    }
 336:
 337:	      private void destroyImages(List images) {
 338:        Iterator iter= images.iterator();
 339:	          while (iter.hasNext()) {
 340:            Image image= (Image)iter.next();
 341:            if (image != null && !image.isDisposed())
 342:                image.dispose();
 343:        }
 344:    }
 345:    
 346:	      protected Control createPageArea(Composite parent) {
 347:        int numPages= fDescriptors.size();
 348:        fScopeParts= new ScopePart[numPages];
 349:        
 350:	          if (numPages == 0) {
 351:            Label label= new Label(parent, SWT.CENTER | SWT.WRAP);
 352:            label.setText(SearchMessages.SearchDialog_noSearchExtension); 
 353:            return label;
 354:        }
 355:        
 356:        fCurrentIndex= getPreferredPageIndex();
 357:        final SearchPageDescriptor currentDesc= getDescriptorAt(fCurrentIndex);
 358:                
 359:        Composite composite= new Composite(parent, SWT.NONE);
 360:        composite.setFont(parent.getFont());
 361:        
 362:        GridLayout layout = new GridLayout();
 363:        layout.marginHeight = 0;
 364:        layout.marginWidth = 0;
 365:        composite.setLayout(layout);
 366:        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
 367:        
 368:        TabFolder folder= new TabFolder(composite, SWT.NONE);
 369:        folder.setLayout(new TabFolderLayout());
 370:        folder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
 371:        folder.setFont(composite.getFont());
 372:        
 373:	          for (int i= 0; i < numPages; i++) {            
 374:            SearchPageDescriptor descriptor= getDescriptorAt(i);
 375:            if (WorkbenchActivityHelper.filterItem(descriptor))
 376:                continue;
 377:            
 378:            final TabItem item= new TabItem(folder, SWT.NONE);
 379:            item.setData("descriptor", descriptor); //$NON-NLS-1$
 380:            item.setText(descriptor.getLabel());
 381:	              item.addDisposeListener(new DisposeListener() {
 382:	                  public void widgetDisposed(DisposeEvent e) {
 383:                    item.setData("descriptor", null); //$NON-NLS-1$
 384:                    if (item.getImage() != null)
 385:                        item.getImage().dispose();
 386:                }
 387:            });
 388:            ImageDescriptor imageDesc= descriptor.getImage();
 389:            if (imageDesc != null)
 390:                item.setImage(imageDesc.createImage());
 391:            
 392:	              if (i == fCurrentIndex) {
 393:                Control pageControl= createPageControl(folder, descriptor);
 394:                pageControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
 395:                item.setControl(pageControl);
 396:                fCurrentPage= currentDesc.getPage();
 397:            }
 398:        }
 399:        
 400:	          folder.addSelectionListener(new SelectionAdapter() {
 401:	              public void widgetSelected(SelectionEvent event) {
 402:                turnToPage(event);
 403:            }
 404:        });
 405:
 406:        folder.setSelection(fCurrentIndex);
 407:        
 408:        return composite;
 409:    }
 410:    
 411:	      protected Control createButtonBar(Composite parent) {
 412:        Composite composite= new Composite(parent, SWT.NONE);
 413:        GridLayout layout= new GridLayout();
 414:        layout.numColumns= 0;   // create 
 415:        layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
 416:        layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
 417:        layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
 418:        layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
 419:        
 420:        composite.setLayout(layout);
 421:        composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 422:    
 423:        // create help control if needed
 424:	          if (isHelpAvailable()) {
 425:            createHelpControl(composite);
 426:        }
 427:        fCustomizeButton= createButton(composite, CUSTOMIZE_ID, SearchMessages.SearchDialog_customize, true); 
 428:        
 429:        Label filler= new Label(composite, SWT.NONE);
 430:        filler.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
 431:        layout.numColumns++;
 432:        
 433:        fReplaceButton= createActionButton(composite, REPLACE_ID, SearchMessages.SearchDialog_replaceAction, true); 
 434:        fReplaceButton.setVisible(fCurrentPage instanceof IReplacePage);
 435:        Button searchButton= createActionButton(composite, SEARCH_ID, SearchMessages.SearchDialog_searchAction, true); 
 436:        searchButton.setEnabled(fDescriptors.size() > 0);
 437:        super.createButtonsForButtonBar(composite);  // cancel button
 438:        
 439:        return composite;
 440:    }
 441:
 442:	      protected boolean performAction(int actionID) {
 443:	          switch (actionID) {
 444:            case CUSTOMIZE_ID:
 445:                handleCustomizePressed();
 446:                return false;
 447:            case CANCEL:
 448:                return true;
 449:            case SEARCH_ID:
 450:	                  if (fCurrentPage != null) {
 451:                    return fCurrentPage.performAction();
 452:                }
 453:                return true;
 454:            case REPLACE_ID:
 455:                boolean isAutoBuilding= SearchPlugin.setAutoBuilding(false);
 456:	                  try {
 457:                    fCustomizeButton.setEnabled(false);
 458:
 459:                    // safe cast, replace button is only visible when the current page is 
 460:                    // a replace page.
 461:                    return ((IReplacePage)fCurrentPage).performReplace();
 462:                } finally {
 463:                    fCustomizeButton.setEnabled(true);
 464:                    SearchPlugin.setAutoBuilding(isAutoBuilding);                
 465:                }
 466:            default:
 467:                return false;
 468:        }    
 469:    }
 470:
 471:	      private SearchPageDescriptor getDescriptorAt(int index) {
 472:        return (SearchPageDescriptor) fDescriptors.get(index);
 473:    }
 474:    
 475:	      private Point getMinSize() {
 476:        if (fMinSize != null)
 477:            return fMinSize;
 478:            
 479:        int x= 0;
 480:        int y= 0;
 481:        int length= fDescriptors.size();
 482:	          for (int i= 0; i < length; i++) {
 483:            Point size= getDescriptorAt(i).getPreferredSize();
 484:            if (size.x != SWT.DEFAULT)
 485:                x= Math.max(x, size.x);
 486:            if (size.y != SWT.DEFAULT)
 487:                y= Math.max(y, size.y);
 488:        }
 489:        
 490:        fMinSize= new Point(x, y);
 491:        return fMinSize;    
 492:    }
 493:    
 494:	      private void turnToPage(SelectionEvent event) {
 495:        final TabItem item= (TabItem) event.item;
 496:        TabFolder folder= item.getParent();
 497:        
 498:        SearchPageDescriptor descriptor= (SearchPageDescriptor) item.getData("descriptor"); //$NON-NLS-1$
 499:        
 500:	          if (item.getControl() == null) {
 501:            item.setControl(createPageControl(folder, descriptor));
 502:        }
 503:        
 504:        Control oldControl= folder.getItem(fCurrentIndex).getControl();
 505:        Point oldSize= oldControl.getSize();
 506:        Control newControl= item.getControl();
 507:        Point newSize= newControl.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
 508:        resizeDialogIfNeeded(oldSize, newSize);
 509:        
 510:        ISearchPage oldPage= fCurrentPage;
 511:	          if (oldPage != null) {
 512:            oldPage.setVisible(false);
 513:        }
 514:        
 515:        fCurrentPage= descriptor.getPage();
 516:        fCurrentIndex= folder.getSelectionIndex();
 517:        
 518:        setPerformActionEnabled(fCurrentPage != null);
 519:	          if (fCurrentPage != null) {
 520:            fCurrentPage.setVisible(true);
 521:        }
 522:        fReplaceButton.setVisible(fCurrentPage instanceof IReplacePage);
 523:        notifyPageChanged();
 524:    }
 525:    
 526:	      private int getPreferredPageIndex() {
 527:        Object element= null;
 528:        ISelection selection= getSelection();
 529:        if (selection instanceof IStructuredSelection)
 530:            element= ((IStructuredSelection) selection).getFirstElement();
 531:        
 532:	          if (element == null) {
 533:            IEditorPart editorPart= getActiveEditor();
 534:	              if (editorPart != null) {
 535:                element= editorPart.getEditorInput();
 536:            }
 537:        }
 538:        int result= 0;
 539:        int level= ISearchPageScoreComputer.LOWEST;
 540:        int size= fDescriptors.size();
 541:	          for (int i= 0; i < size; i++) {
 542:            SearchPageDescriptor descriptor= (SearchPageDescriptor) fDescriptors.get(i);
 543:            if (fInitialPageId != null && fInitialPageId.equals(descriptor.getId()))
 544:                return i;
 545:            
 546:            int newLevel= descriptor.computeScore(element);
 547:	              if (newLevel > level) {
 548:                level= newLevel;
 549:                result= i;
 550:            }
 551:        }
 552:        return result;
 553:    }
 554:
 555:    /*
 556:     * Implements method from ISearchPageContainer
 557:     */
 558:	      public IRunnableContext getRunnableContext() {
 559:        return this;
 560:    }
 561:
 562:    /*
 563:     * Implements method from ISearchPageContainer
 564:     */    
 565:	      public int getSelectedScope() {
 566:        if (fScopeParts[fCurrentIndex] == null)
 567:            // safe code - should not happen
 568:            return ISearchPageContainer.WORKSPACE_SCOPE;
 569:        
 570:        return fScopeParts[fCurrentIndex].getSelectedScope();
 571:    }
 572:
 573:    /*
 574:     * Implements method from ISearchPageContainer
 575:     */
 576:	      public IWorkingSet[] getSelectedWorkingSets() {
 577:        if (fScopeParts[fCurrentIndex] == null)
 578:            // safe code - should not happen
 579:            return null;
 580:        
 581:        return fScopeParts[fCurrentIndex].getSelectedWorkingSets();
 582:    }
 583:    
 584:	      public String[] getEnclosingProjectNames() {
 585:        return fCurrentEnclosingProject;
 586:    }
 587:    
 588:    
 589:	      public String[] getSelectedProjectNames() {
 590:	          if (getSelectedScope() == SELECTED_PROJECTS_SCOPE) {
 591:            return getEnclosingProjectNames();
 592:        }
 593:        return null;
 594:    }
 595:
 596:    /*
 597:     * Implements method from ISearchPageContainer
 598:     */
 599:	      public void setSelectedScope(int scope) {
 600:        if (fScopeParts[fCurrentIndex] != null)
 601:            fScopeParts[fCurrentIndex].setSelectedScope(scope);
 602:    }
 603:
 604:    /*
 605:     * Implements method from ISearchPageContainer
 606:     */
 607:	      public boolean hasValidScope() {
 608:        return getSelectedScope() != WORKING_SET_SCOPE || getSelectedWorkingSets() != null;
 609:    }
 610:    
 611:    /*
 612:     * Implements method from ISearchPageContainer
 613:     */
 614:	      public void setSelectedWorkingSets(IWorkingSet[] workingSets) {
 615:        if (fScopeParts[fCurrentIndex] != null)
 616:            fScopeParts[fCurrentIndex].setSelectedWorkingSets(workingSets);
 617:    }
 618:
 619:    /*
 620:     * Overrides method from ExtendedDialogWindow
 621:     */
 622:	      public void setPerformActionEnabled(boolean state) {
 623:        fLastEnableState= state;
 624:        super.setPerformActionEnabled(state && hasValidScope());
 625:    } 
 626:
 627:    /**
 628:     * Notify that the scope selection has changed
 629:     * <p>
 630:     * Note: This is a special method to be called only from the ScopePart
 631:     * </p>
 632:     */
 633:	      public void notifyScopeSelectionChanged() {
 634:        setPerformActionEnabled(fLastEnableState);
 635:    }
 636:
 637:	      private Control createPageControl(Composite parent, final SearchPageDescriptor descriptor) {
 638:        
 639:        // Page wrapper
 640:        final Composite pageWrapper= new Composite(parent, SWT.NONE);
 641:        GridLayout layout= new GridLayout();
 642:        layout.marginWidth= 0;
 643:        layout.marginHeight= 0;
 644:        pageWrapper.setLayout(layout);
 645:        
 646:        applyDialogFont(pageWrapper);
 647:        
 648:	          BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
 649:	              public void run() {
 650:	                  SafeRunner.run(new ISafeRunnable() {
 651:	                      public void run() throws Exception {
 652:                        // create page and control
 653:                        ISearchPage page= descriptor.createObject(SearchDialog.this);
 654:	                          if (page != null) {
 655:                            page.createControl(pageWrapper);
 656:                        }
 657:                    }
 658:	                      public void handleException(Throwable ex) {
 659:	                          if (ex instanceof CoreException) {
 660:                            ExceptionHandler.handle((CoreException) ex, getShell(), SearchMessages.Search_Error_createSearchPage_title, Messages.format(SearchMessages.Search_Error_createSearchPage_message, descriptor.getLabel())); 
 661:                        } else {
 662:                            ExceptionHandler.displayMessageDialog(ex, getShell(), SearchMessages.Search_Error_createSearchPage_title, Messages.format(SearchMessages.Search_Error_createSearchPage_message, descriptor.getLabel())); 
 663:                        }
 664:                    }
 665:                });
 666:            }
 667:        });
 668:        
 669:        ISearchPage page= descriptor.getPage();
 670:	          if (page == null || page.getControl() == null) {
 671:            Composite container= new Composite(parent, SWT.NONE);
 672:            Label label= new Label(container, SWT.WRAP);
 673:            label.setText(Messages.format(SearchMessages.SearchDialog_error_pageCreationFailed, descriptor.getLabel())); 
 674:            container.setLayout(new GridLayout());
 675:            label.setLayoutData(new GridData());
 676:            return container;
 677:        }
 678:        
 679:        page.getControl().setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
 680:        
 681:        // Search scope
 682:        boolean showScope= descriptor.showScopeSection();
 683:	          if (showScope) {
 684:            Composite c= new Composite(pageWrapper, SWT.NONE);
 685:            c.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
 686:            c.setLayout(new GridLayout());
 687:            
 688:            int index= fDescriptors.indexOf(descriptor);
 689:            fScopeParts[index]= new ScopePart(this, descriptor.canSearchInProjects());
 690:            Control part= fScopeParts[index].createPart(c);
 691:            applyDialogFont(part);
 692:            part.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
 693:            fScopeParts[index].setVisible(true);
 694:        }
 695:        
 696:        return pageWrapper;
 697:    }
 698:    
 699:	      private void resizeDialogIfNeeded(Point oldSize, Point newSize) {
 700:        if (oldSize == null || newSize == null)
 701:            return;
 702:            Shell shell= getShell();
 703:        Point shellSize= shell.getSize();
 704:	          if (mustResize(oldSize, newSize)) {
 705:            if (newSize.x > oldSize.x)
 706:                shellSize.x+= (newSize.x-oldSize.x);
 707:            if (newSize.y > oldSize.y)
 708:                shellSize.y+= (newSize.y-oldSize.y);
 709:            shell.setSize(shellSize);
 710:                    shell.layout(true);
 711:        }
 712:    }
 713:    
 714:	      private boolean mustResize(Point currentSize, Point newSize) {
 715:        return currentSize.x < newSize.x || currentSize.y < newSize.y;
 716:    }
 717:    
 718:    /* (non-Javadoc)
 719:     * @see org.eclipse.jface.dialogs.Dialog#close()
 720:     */
 721:	      public boolean close() {
 722:	          for (int i= 0; i < fDescriptors.size(); i++) {
 723:            SearchPageDescriptor desc= (SearchPageDescriptor) fDescriptors.get(i);
 724:            desc.dispose();
 725:        }
 726:        return super.close();
 727:    }
 728:
 729:    /* (non-Javadoc)
 730:     * @see org.eclipse.jface.dialogs.IPageChangeProvider#getSelectedPage()
 731:     */
 732:	      public Object getSelectedPage() {
 733:        return fCurrentPage;
 734:    }
 735:
 736:    /* (non-Javadoc)
 737:     * @see org.eclipse.jface.dialogs.IPageChangeProvider#addPageChangedListener(org.eclipse.jface.dialogs.IPageChangedListener)
 738:     */
 739:	      public void addPageChangedListener(IPageChangedListener listener) {
 740:	          if (fPageChangeListeners == null) {
 741:            fPageChangeListeners= new ListenerList();
 742:        }
 743:        fPageChangeListeners.add(listener);
 744:    }
 745:
 746:    /* (non-Javadoc)
 747:     * @see org.eclipse.jface.dialogs.IPageChangeProvider#removePageChangedListener(org.eclipse.jface.dialogs.IPageChangedListener)
 748:     */
 749:	      public void removePageChangedListener(IPageChangedListener listener) {
 750:        fPageChangeListeners.remove(listener);
 751:    }
 752:    
 753:	      private void notifyPageChanged() {
 754:	          if (fPageChangeListeners != null && !fPageChangeListeners.isEmpty()) {
 755:            // Fires the page change event
 756:            final PageChangedEvent event= new PageChangedEvent(this, getSelectedPage());
 757:            Object[] listeners= fPageChangeListeners.getListeners();
 758:	              for (int i= 0; i < listeners.length; ++i) {
 759:                final IPageChangedListener l= (IPageChangedListener) listeners[i];
 760:	                  SafeRunner.run(new SafeRunnable() {
 761:	                      public void run() {
 762:                        l.pageChanged(event);
 763:                    }
 764:                });
 765:            }
 766:        }
 767:    }
 768:}