예제 #1
0
 public boolean isHorizontal() {
   Sash sash = (Sash) getWidget();
   if (sash != null && !sash.isDisposed()) {
     return ((sash.getStyle() & SWT.HORIZONTAL) == SWT.HORIZONTAL);
   }
   return true;
 }
예제 #2
0
  protected void layout() {
    Rectangle parentArea = this.composite.getClientArea();
    int width = parentArea.width;
    int height = parentArea.height;

    Rectangle sashBounds = sash.getBounds();

    resultText.setBounds(0, 0, width, sashBounds.y);
    userText.setBounds(0, sashBounds.y + 3, width, height - sashBounds.y - 3);
    sash.setBounds(0, sashBounds.y, width, 3);
  }
예제 #3
0
  /** @param args */
  public static void main(String[] args) {
    Display display = new Display();
    final Shell shell = new Shell(display);
    Button button1 = new Button(shell, SWT.PUSH);
    button1.setText("Button 1");
    final Sash sash = new Sash(shell, SWT.VERTICAL);
    Button button2 = new Button(shell, SWT.PUSH);
    button2.setText("Button 2");

    final FormLayout form = new FormLayout();
    shell.setLayout(form);

    FormData button1Data = new FormData();
    button1Data.left = new FormAttachment(0, 0);
    button1Data.right = new FormAttachment(sash, 0);
    button1Data.top = new FormAttachment(0, 0);
    button1Data.bottom = new FormAttachment(100, 0);
    button1.setLayoutData(button1Data);

    final int limit = 20, percent = 50;
    final FormData sashData = new FormData();
    sashData.left = new FormAttachment(percent, 0);
    sashData.top = new FormAttachment(0, 0);
    sashData.bottom = new FormAttachment(100, 0);
    sash.setLayoutData(sashData);
    sash.addListener(
        SWT.Selection,
        new Listener() {
          public void handleEvent(Event e) {
            Rectangle sashRect = sash.getBounds();
            Rectangle shellRect = shell.getClientArea();
            int right = shellRect.width - sashRect.width - limit;
            e.x = Math.max(Math.min(e.x, right), limit);
            if (e.x != sashRect.x) {
              sashData.left = new FormAttachment(0, e.x);
              shell.layout();
            }
          }
        });

    FormData button2Data = new FormData();
    button2Data.left = new FormAttachment(sash, 0);
    button2Data.right = new FormAttachment(100, 0);
    button2Data.top = new FormAttachment(0, 0);
    button2Data.bottom = new FormAttachment(100, 0);
    button2.setLayoutData(button2Data);

    shell.pack();
    shell.open();
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch()) display.sleep();
    }
    display.dispose();
  }
 /**
  * Create the sash with right control on the right. Note that this method assumes GridData for the
  * layout data of the rightControl.
  *
  * @param composite
  * @param rightControl
  * @return Sash
  * @since 3.1
  */
 protected Sash createSash(final Composite composite, final Control rightControl) {
   final Sash sash = new Sash(composite, SWT.VERTICAL);
   sash.setLayoutData(new GridData(GridData.FILL_VERTICAL));
   sash.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
   // the following listener resizes the tree control based on sash deltas.
   // If necessary, it will also grow/shrink the dialog.
   sash.addListener(
       SWT.Selection,
       event -> {
         if (event.detail == SWT.DRAG) {
           return;
         }
         int shift = event.x - sash.getBounds().x;
         GridData data = (GridData) rightControl.getLayoutData();
         int newWidthHint = data.widthHint + shift;
         if (newWidthHint < 20) {
           return;
         }
         Point computedSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
         Point currentSize = getShell().getSize();
         // if the dialog wasn't of a custom size we know we can shrink
         // it if necessary based on sash movement.
         boolean customSize = !computedSize.equals(currentSize);
         data.widthHint = newWidthHint;
         setLastTreeWidth(newWidthHint);
         composite.layout(true);
         // recompute based on new widget size
         computedSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
         // if the dialog was of a custom size then increase it only if
         // necessary.
         if (customSize) {
           computedSize.x = Math.max(computedSize.x, currentSize.x);
         }
         computedSize.y = Math.max(computedSize.y, currentSize.y);
         if (computedSize.equals(currentSize)) {
           return;
         }
         setShellSize(computedSize.x, computedSize.y);
         lastShellSize = getShell().getSize();
       });
   return sash;
 }
예제 #5
0
  protected void resized() {
    Rectangle parentArea = this.composite.getClientArea();
    int width = parentArea.width;
    int height = parentArea.height;

    int userTextHeight = (int) (height * (1 - defaultRatio));
    if (userTextHeight < 25) userTextHeight = 25;

    resultText.setBounds(0, 0, width, height - userTextHeight - 3);
    userText.setBounds(0, height - userTextHeight, width, userTextHeight);
    sash.setBounds(0, height - userTextHeight - 3, width, 3);
  }
예제 #6
0
  @Override
  public void createPartControl(Composite parent) {

    this.setPartName("Ocaml Toplevel");

    composite = new Composite(parent, SWT.BORDER);
    composite.addControlListener(
        new ControlAdapter() {
          @Override
          public void controlResized(ControlEvent e) {
            resized();
          }
        });

    userText = new StyledText(this.composite, SWT.V_SCROLL);
    userText.setWordWrap(true);
    resultText = new StyledText(this.composite, SWT.V_SCROLL);
    resultText.setWordWrap(true);

    sash = new Sash(composite, SWT.HORIZONTAL | SWT.SMOOTH);

    sash.addSelectionListener(
        new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            sash.setBounds(e.x, e.y, e.width, e.height);
            layout();
          }
        });

    Color c =
        Display.findDisplay(Thread.currentThread()).getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
    sash.setBackground(c);

    toplevel = new Toplevel(this, userText, resultText);

    IActionBars actionBars = this.getViewSite().getActionBars();
    IMenuManager dropDownMenu = actionBars.getMenuManager();
    IToolBarManager toolBarManager = actionBars.getToolBarManager();

    ImageDescriptor iconAdd = ImageRepository.getImageDescriptor(ImageRepository.ICON_ADD);
    Action actionNewToplevel =
        new Action("New toplevel", iconAdd) {
          @Override
          public void run() {
            try {
              IWorkbenchPage page =
                  PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
              OcamlToplevelView.this.secondaryId = "ocamltoplevelview" + new Random().nextInt();
              page.showView(ID, OcamlToplevelView.this.secondaryId, IWorkbenchPage.VIEW_ACTIVATE);
            } catch (Exception e) {
              OcamlPlugin.logError("ocaml plugin error", e);
            }
          }
        };

    ImageDescriptor iconReset = ImageRepository.getImageDescriptor(ImageRepository.ICON_RESET);
    Action actionReset =
        new Action("Reset", iconReset) {
          @Override
          public void run() {
            toplevel.reset();
          }
        };

    ImageDescriptor iconInterrupt =
        ImageRepository.getImageDescriptor(ImageRepository.ICON_INTERRUPT);
    Action actionBreak =
        new Action("Interrupt", iconInterrupt) {
          @Override
          public void run() {
            toplevel.interrupt();
          }
        };

    ImageDescriptor iconClear = ImageRepository.getImageDescriptor(ImageRepository.ICON_CLEAR);
    Action actionClear =
        new Action("Clear", iconClear) {
          @Override
          public void run() {
            toplevel.clear();
          }
        };

    ImageDescriptor iconHelp = ImageRepository.getImageDescriptor(ImageRepository.ICON_HELP);
    Action actionHelp =
        new Action("Help", iconHelp) {
          @Override
          public void run() {
            toplevel.help();
          }
        };

    Action actionUseTopfind =
        new Action("Use Topfind") {
          @Override
          public void run() {
            toplevel.eval("#use \"topfind\";;");
          }
        };

    dropDownMenu.add(actionUseTopfind);

    toolBarManager.add(actionBreak);
    toolBarManager.add(actionClear);
    toolBarManager.add(actionReset);
    toolBarManager.add(actionNewToplevel);
    toolBarManager.add(actionHelp);

    if (bStartWhenCreated) toplevel.start();

    OcamlPlugin.setLastFocusedToplevelInstance(this);
  }
예제 #7
0
  /**
   * Creates and returns the composite of the view.
   *
   * @return Composite
   */
  public Composite getComposite(Composite parent) {
    // composite is the composite we are building, it gets a formlayout
    Composite composite = new Composite(parent, SWT.NONE);
    FormLayout layout = new FormLayout();
    composite.setLayout(layout);
    layout.marginHeight = 5;
    layout.marginWidth = 5;
    FormData data;

    // creates the sash on the right of the tree
    final Sash vertSash = new Sash(composite, SWT.VERTICAL);
    data = new FormData();
    data.top = new FormAttachment(0, 0);
    data.bottom = new FormAttachment(100, 0);
    data.left = new FormAttachment(25, 0);
    vertSash.setLayoutData(data);
    vertSash.addSelectionListener(
        new SelectionAdapter() { // makes the sashes resizeable
          public void widgetSelected(SelectionEvent event) {
            ((FormData) vertSash.getLayoutData()).left = new FormAttachment(0, event.x);
            vertSash.getParent().layout();
          }
        });

    // construct tree in left side of composite
    Tree leftTree = new Tree(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
    data = new FormData();
    data.bottom = new FormAttachment(100, 0);
    data.top = new FormAttachment(0, 0);
    data.right = new FormAttachment(vertSash, 0);
    data.left = new FormAttachment(0, 0);
    leftTree.setLayoutData(data);
    treeViewer = new TreeViewer(leftTree);
    treeViewer.setContentProvider(new MailBoxTreeContentProvider(control));
    treeViewer.setLabelProvider(new MailBoxTreeLabelProvider());
    treeViewer.setInput("root");

    // constructs the web browser
    Composite window = getFightPane(composite);
    data = new FormData();
    data.left = new FormAttachment(vertSash, 0);
    data.top = new FormAttachment(0, 0);
    data.right = new FormAttachment(100, 0);
    data.bottom = new FormAttachment(100, 0);
    window.setLayoutData(data);

    // references to the underlying tree object
    final Tree tree = treeViewer.getTree();
    // keylistener to handle deletions
    tree.addKeyListener(
        new KeyListener() {
          public void keyPressed(KeyEvent e) {
            if (e.character == 0x7f) {
              if (tree.getSelection().length == 1
                  && tree.getSelection()[0].getData() instanceof Folder) {
                // if there is one item selected and it is a folder, delete it
                deleteFolderAction.run();
              } else {
                // otherwise delete selected feeds
                unSubscribeAction.run();
              }
            }
          }

          public void keyReleased(KeyEvent e) {}
        });

    /// edits the right click menu to add appropriate actions
    final MenuManager treeMenuManager = new MenuManager();
    treeMenuManager.addMenuListener(
        new IMenuListener() {
          public void menuAboutToShow(IMenuManager arg0) {
            // first remove all actions, then add appropriate ones based on context
            treeMenuManager.removeAll();
            if (treeViewer.getSelection() instanceof IStructuredSelection) {
              IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
              if (selection.size() == 1) {
                Object o = selection.getFirstElement();
                // of the object is a folder add the following actions to the menu
                if (o instanceof Folder) {
                  Folder f = (Folder) o;
                  try {
                    treeMenuManager.add(subscribeAction);
                    treeMenuManager.add(new Separator());
                    treeMenuManager.add(newFolderAction);
                    // as long as its not the top folder we let the user delete it
                    if (f.getId() != control.getSubscribedFeeds().getId())
                      treeMenuManager.add(deleteFolderAction);
                  } catch (ControlException e) {
                    control.setStatus("Problem fetching top level folder");
                  }
                }
                // if its a feed we want different actions
                if (o instanceof Feed) {
                  Feed f = (Feed) o;
                  try {
                    // special actions for the trash and outbox
                    if (f.getId() == control.getTrash().getId()) {
                      treeMenuManager.add(emptyTrashAction);
                    } else if (f.getId() == control.getOutbox().getId()) {
                      treeMenuManager.add(newArticleAction);
                      treeMenuManager.add(exportOutboxAction);
                    } else {
                      // actions for normal feeds
                      treeMenuManager.add(updateFeedAction);
                      treeMenuManager.add(unSubscribeAction);
                      treeMenuManager.add(feedPropertiesAction);
                    }
                  } catch (ControlException e) {
                    control.setStatus("Problem fetching top level folder");
                  }
                }
              }
              // if there are multiple selections, do different things
              else if (selection.size() > 1) {
                boolean allFeeds = true;
                int trashId, outBoxId;
                // gets the trashid and boxid once so we don't need to query the database every
                // iteration
                // to check if the feed is trash or outbox
                try {
                  trashId = control.getTrash().getId();
                  outBoxId = control.getOutbox().getId();
                } catch (ControlException e) {
                  trashId = 0;
                  outBoxId = 0;
                }
                // gets iterator over selection
                Iterator iter = selection.iterator();
                // iterates through selection to check if the selection is only feeds
                while (iter.hasNext()) {
                  Object o = iter.next();
                  if (!(o instanceof Feed)) {
                    allFeeds = false;
                    break;
                  }
                  if (((Feed) o).getId() == trashId || ((Feed) o).getId() == outBoxId) {
                    allFeeds = false;
                    break;
                  }
                }
                if (allFeeds) {
                  // if the only selected items are feeds, then let them update all the selected
                  // feeds or unsubscribe
                  treeMenuManager.add(updateFeedAction);
                  treeMenuManager.add(unSubscribeAction);
                }
              }
            }
          }
        });
    // set the menu
    tree.setMenu(treeMenuManager.createContextMenu(tree));

    return composite;
  }
  public Composite createSashForm(final Composite composite) {
    if (!tv.isTabViewsEnabled()) {
      tableComposite = tv.createMainPanel(composite);
      return tableComposite;
    }

    ConfigurationManager configMan = ConfigurationManager.getInstance();

    int iNumViews = 0;

    UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
    UISWTViewEventListenerWrapper[] pluginViews = null;
    if (uiFunctions != null) {
      UISWTInstance pluginUI = uiFunctions.getUISWTInstance();

      if (pluginUI != null) {
        pluginViews = pluginUI.getViewListeners(tv.getTableID());
        iNumViews += pluginViews.length;
      }
    }

    if (iNumViews == 0) {
      tableComposite = tv.createMainPanel(composite);
      return tableComposite;
    }

    FormData formData;

    final Composite form = new Composite(composite, SWT.NONE);
    FormLayout flayout = new FormLayout();
    flayout.marginHeight = 0;
    flayout.marginWidth = 0;
    form.setLayout(flayout);
    GridData gridData;
    gridData = new GridData(GridData.FILL_BOTH);
    form.setLayoutData(gridData);

    // Create them in reverse order, so we can have the table auto-grow, and
    // set the tabFolder's height manually

    final int TABHEIGHT = 20;
    tabFolder = new CTabFolder(form, SWT.TOP | SWT.BORDER);
    tabFolder.setMinimizeVisible(true);
    tabFolder.setTabHeight(TABHEIGHT);
    final int iFolderHeightAdj = tabFolder.computeSize(SWT.DEFAULT, 0).y;

    final Sash sash = new Sash(form, SWT.HORIZONTAL);

    tableComposite = tv.createMainPanel(form);
    Composite cFixLayout = tableComposite;
    while (cFixLayout != null && cFixLayout.getParent() != form) {
      cFixLayout = cFixLayout.getParent();
    }
    if (cFixLayout == null) {
      cFixLayout = tableComposite;
    }
    GridLayout layout = new GridLayout();
    layout.numColumns = 1;
    layout.horizontalSpacing = 0;
    layout.verticalSpacing = 0;
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    cFixLayout.setLayout(layout);

    // FormData for Folder
    formData = new FormData();
    formData.left = new FormAttachment(0, 0);
    formData.right = new FormAttachment(100, 0);
    formData.bottom = new FormAttachment(100, 0);
    int iSplitAt = configMan.getIntParameter(tv.getPropertiesPrefix() + ".SplitAt", 3000);
    // Was stored at whole
    if (iSplitAt < 100) {
      iSplitAt *= 100;
    }

    double pct = iSplitAt / 10000.0;
    if (pct < 0.03) {
      pct = 0.03;
    } else if (pct > 0.97) {
      pct = 0.97;
    }

    // height will be set on first resize call
    sash.setData("PCT", new Double(pct));
    tabFolder.setLayoutData(formData);
    final FormData tabFolderData = formData;

    // FormData for Sash
    formData = new FormData();
    formData.left = new FormAttachment(0, 0);
    formData.right = new FormAttachment(100, 0);
    formData.bottom = new FormAttachment(tabFolder);
    formData.height = 5;
    sash.setLayoutData(formData);

    // FormData for table Composite
    formData = new FormData();
    formData.left = new FormAttachment(0, 0);
    formData.right = new FormAttachment(100, 0);
    formData.top = new FormAttachment(0, 0);
    formData.bottom = new FormAttachment(sash);
    cFixLayout.setLayoutData(formData);

    // Listeners to size the folder
    sash.addSelectionListener(
        new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            final boolean FASTDRAG = true;

            if (FASTDRAG && e.detail == SWT.DRAG) {
              return;
            }

            if (tabFolder.getMinimized()) {
              tabFolder.setMinimized(false);
              refreshSelectedSubView();
              ConfigurationManager configMan = ConfigurationManager.getInstance();
              configMan.setParameter(tv.getPropertiesPrefix() + ".subViews.minimized", false);
            }

            Rectangle area = form.getClientArea();
            tabFolderData.height = area.height - e.y - e.height - iFolderHeightAdj;
            form.layout();

            Double l = new Double((double) tabFolder.getBounds().height / form.getBounds().height);
            sash.setData("PCT", l);
            if (e.detail != SWT.DRAG) {
              ConfigurationManager configMan = ConfigurationManager.getInstance();
              configMan.setParameter(
                  tv.getPropertiesPrefix() + ".SplitAt", (int) (l.doubleValue() * 10000));
            }
          }
        });

    final CTabFolder2Adapter folderListener =
        new CTabFolder2Adapter() {
          public void minimize(CTabFolderEvent event) {
            tabFolder.setMinimized(true);
            tabFolderData.height = iFolderHeightAdj;
            CTabItem[] items = tabFolder.getItems();
            for (int i = 0; i < items.length; i++) {
              CTabItem tabItem = items[i];
              tabItem.getControl().setVisible(false);
            }
            form.layout();

            UISWTViewCore view = getActiveSubView();
            if (view != null) {
              view.triggerEvent(UISWTViewEvent.TYPE_FOCUSLOST, null);
            }

            ConfigurationManager configMan = ConfigurationManager.getInstance();
            configMan.setParameter(tv.getPropertiesPrefix() + ".subViews.minimized", true);
          }

          public void restore(CTabFolderEvent event) {
            tabFolder.setMinimized(false);
            CTabItem selection = tabFolder.getSelection();
            if (selection != null) {
              selection.getControl().setVisible(true);
            }
            form.notifyListeners(SWT.Resize, null);

            UISWTViewCore view = getActiveSubView();
            if (view != null) {
              view.triggerEvent(UISWTViewEvent.TYPE_FOCUSGAINED, null);
            }
            refreshSelectedSubView();

            ConfigurationManager configMan = ConfigurationManager.getInstance();
            configMan.setParameter(tv.getPropertiesPrefix() + ".subViews.minimized", false);
          }
        };
    tabFolder.addCTabFolder2Listener(folderListener);

    tabFolder.addSelectionListener(
        new SelectionListener() {
          public void widgetSelected(SelectionEvent e) {
            // make sure its above
            try {
              ((CTabItem) e.item).getControl().setVisible(true);
              ((CTabItem) e.item).getControl().moveAbove(null);

              // TODO: Need to viewDeactivated old one
              UISWTViewCore view = getActiveSubView();
              if (view != null) {
                view.triggerEvent(UISWTViewEvent.TYPE_FOCUSGAINED, null);
              }

            } catch (Exception t) {
            }
          }

          public void widgetDefaultSelected(SelectionEvent e) {}
        });

    tabFolder.addMouseListener(
        new MouseAdapter() {
          public void mouseDown(MouseEvent e) {
            if (tabFolder.getMinimized()) {
              folderListener.restore(null);
              // If the user clicked down on the restore button, and we restore
              // before the CTabFolder does, CTabFolder will minimize us again
              // There's no way that I know of to determine if the mouse is
              // on that button!

              // one of these will tell tabFolder to cancel
              e.button = 0;
              tabFolder.notifyListeners(SWT.MouseExit, null);
            }
          }
        });

    form.addListener(
        SWT.Resize,
        new Listener() {
          public void handleEvent(Event e) {
            if (tabFolder.getMinimized()) {
              return;
            }

            Double l = (Double) sash.getData("PCT");
            if (l != null) {
              tabFolderData.height =
                  (int) (form.getBounds().height * l.doubleValue()) - iFolderHeightAdj;
              form.layout();
            }
          }
        });

    // Call plugin listeners
    if (pluginViews != null) {
      for (UISWTViewEventListenerWrapper l : pluginViews) {
        if (l != null) {
          try {
            UISWTViewImpl view = new UISWTViewImpl(tv.getTableID(), l.getViewID(), l, null);
            addTabView(view);
          } catch (Exception e) {
            // skip, plugin probably specifically asked to not be added
          }
        }
      }
    }

    if (configMan.getBooleanParameter(tv.getPropertiesPrefix() + ".subViews.minimized", false)) {
      tabFolder.setMinimized(true);
      tabFolderData.height = iFolderHeightAdj;
    } else {
      tabFolder.setMinimized(false);
    }

    tabFolder.setSelection(0);

    return form;
  }
예제 #9
0
  /* (non-Javadoc)
   * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
   */
  @Override
  public void createPartControl(final Composite parent) {
    parent.setLayout(new GridLayout(6, true));

    CLabel clRuns = new CLabel(parent, SWT.LEFT);
    clRuns.setText(UITexts.test_view_runs);

    tRuns = new Text(parent, SWT.NONE);
    tRuns.setText("0"); // $NON-NLS-1$
    tRuns.setEditable(false);

    CLabel clErrors = new CLabel(parent, SWT.LEFT);
    clErrors.setText(UITexts.test_view_errors);
    clErrors.setImage(HaskellUIImages.getImage(IImageNames.ERROR_OVERLAY));

    tErrors = new Text(parent, SWT.NONE);
    tErrors.setText("0"); // $NON-NLS-1$
    tErrors.setEditable(false);

    CLabel clFailures = new CLabel(parent, SWT.LEFT);
    clFailures.setText(UITexts.test_view_failures);
    clFailures.setImage(HaskellUIImages.getImage(IImageNames.FAILURE_OVERLAY));

    tFailures = new Text(parent, SWT.NONE);
    tFailures.setText("0"); // $NON-NLS-1$
    tFailures.setEditable(false);

    final Composite mainComposite = new Composite(parent, SWT.NONE);
    final GridData gd =
        new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
    gd.horizontalSpan = 6;
    mainComposite.setLayoutData(gd);
    FormLayout fl = new FormLayout();
    mainComposite.setLayout(fl);

    testTree = new TreeViewer(mainComposite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
    final Sash sash = new Sash(mainComposite, SWT.HORIZONTAL);

    FormData fd = new FormData();
    fd.top = new FormAttachment(0);
    fd.left = new FormAttachment(0);
    fd.right = new FormAttachment(100);
    fd.bottom = new FormAttachment(sash, 0);
    testTree.getTree().setLayoutData(fd);
    testTree.setContentProvider(new TestResultCP());
    testTree.setLabelProvider(new TestResultLP());

    CLabel clOutput = new CLabel(mainComposite, SWT.LEFT);
    clOutput.setText(UITexts.test_view_text);

    final FormData sashData = new FormData();
    sashData.top = new FormAttachment(50, 0);
    sashData.left = new FormAttachment(0);
    sashData.right = new FormAttachment(100);
    sash.setLayoutData(sashData);

    fd = new FormData();
    fd.top = new FormAttachment(sash, 0);
    fd.left = new FormAttachment(0);
    fd.right = new FormAttachment(100);
    clOutput.setLayoutData(fd);

    testText = new StyledText(mainComposite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);

    fd = new FormData();
    fd.top = new FormAttachment(clOutput, 0);
    fd.left = new FormAttachment(0, 0);
    fd.right = new FormAttachment(100);
    fd.bottom = new FormAttachment(100);
    testText.setLayoutData(fd);

    testTree.addSelectionChangedListener(
        new ISelectionChangedListener() {

          @Override
          public void selectionChanged(final SelectionChangedEvent paramSelectionChangedEvent) {
            Object o =
                ((IStructuredSelection) paramSelectionChangedEvent.getSelection())
                    .getFirstElement();
            if (o instanceof TestResult) {
              String txt = ((TestResult) o).getText();
              if (txt == null) {
                txt = ""; // $NON-NLS-1$
              }
              testText.setText(txt);
            }
          }
        });

    testTree.addDoubleClickListener(
        new IDoubleClickListener() {

          @Override
          public void doubleClick(final DoubleClickEvent paramDoubleClickEvent) {
            Object o =
                ((IStructuredSelection) paramDoubleClickEvent.getSelection()).getFirstElement();
            if (o instanceof TestResult) {
              TestResult tr = (TestResult) o;
              if (tr.getLocation() != null && tr.getProject() != null) {
                try {
                  OpenDefinitionHandler.openInEditor(tr.getLocation(), tr.getProject());
                } catch (Throwable t) {
                  HaskellCorePlugin.log(t);
                }
              }
            }
          }
        });

    sash.addListener(
        SWT.Selection,
        new Listener() {

          @Override
          public void handleEvent(final Event event) {
            Rectangle clientArea = mainComposite.getClientArea();
            Rectangle sashRect = sash.getBounds();
            int top = clientArea.height - 70; // bottom minimum
            event.y = Math.max(Math.min(event.y, top), 30); // top minimum
            if (event.y != sashRect.y) {
              sashData.top = new FormAttachment(0, event.y);
              mainComposite.layout();
            }
          }
        });

    IToolBarManager tmgr = getViewSite().getActionBars().getToolBarManager();
    HistoryAction act = new HistoryAction();

    tmgr.add(act);
  }