/**
  * Controls how text and images will be displayed in the receiver. The argument should be one of
  * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>.
  *
  * <p>Note that due to a restriction on some platforms, the first column is always left aligned.
  *
  * @param alignment the new alignment
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setAlignment(int alignment) {
   checkWidget();
   if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return;
   int index = parent.indexOf(this);
   if (index == -1 || index == 0) return;
   style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER);
   style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER);
   NSOutlineView outlineView = ((NSOutlineView) parent.view);
   NSTableHeaderView headerView = outlineView.headerView();
   if (headerView == null) return;
   index = parent.indexOf(nsColumn);
   NSRect rect = headerView.headerRectOfColumn(index);
   headerView.setNeedsDisplayInRect(rect);
   rect = outlineView.rectOfColumn(index);
   parent.view.setNeedsDisplayInRect(rect);
 }
Esempio n. 2
0
 public void renderInitialization(final Widget widget) throws IOException {
   Tree tree = (Tree) widget;
   JSWriter writer = JSWriter.getWriterFor(tree);
   StringBuffer style = new StringBuffer();
   if ((tree.getStyle() & SWT.MULTI) != 0) {
     style.append("multi|");
   }
   if ((tree.getStyle() & SWT.CHECK) != 0) {
     style.append("check|");
   }
   if ((tree.getStyle() & SWT.VIRTUAL) != 0) {
     style.append("virtual|");
   }
   writer.newWidget("org.eclipse.swt.widgets.Tree", new Object[] {style.toString()});
   ControlLCAUtil.writeStyleFlags(tree);
 }
Esempio n. 3
0
 public static TreeItem getTreeItem(Tree tree, Object data) {
   for (TreeItem item : tree.getItems()) {
     if (item.getData() == data) {
       return item;
     }
   }
   return null;
 }
Esempio n. 4
0
 public void preserveValues(final Widget widget) {
   Tree tree = (Tree) widget;
   ControlLCAUtil.preserveValues((Control) widget);
   IWidgetAdapter adapter = WidgetUtil.getAdapter(tree);
   adapter.preserve(PROP_SELECTION_LISTENERS, Boolean.valueOf(SelectionEvent.hasListener(tree)));
   adapter.preserve(PROP_HEADER_HEIGHT, new Integer(tree.getHeaderHeight()));
   adapter.preserve(PROP_HEADER_VISIBLE, Boolean.valueOf(tree.getHeaderVisible()));
   int[] values = tree.getColumnOrder();
   Integer[] columnOrder = new Integer[values.length];
   for (int i = 0; i < values.length; i++) {
     columnOrder[i] = new Integer(values[i]);
   }
   adapter.preserve(PROP_COLUMN_ORDER, columnOrder);
   adapter.preserve(PROP_SCROLL_LEFT, getScrollLeft(tree));
   adapter.preserve(PROP_HAS_H_SCROLL_BAR, hasHScrollBar(tree));
   adapter.preserve(PROP_HAS_V_SCROLL_BAR, hasVScrollBar(tree));
   WidgetLCAUtil.preserveCustomVariant(tree);
 }
 public void setImage(Image image) {
   checkWidget();
   if (image != null && image.isDisposed()) {
     error(SWT.ERROR_INVALID_ARGUMENT);
   }
   super.setImage(image);
   NSTableHeaderView headerView = ((NSOutlineView) parent.view).headerView();
   if (headerView == null) return;
   int index = parent.indexOf(nsColumn);
   NSRect rect = headerView.headerRectOfColumn(index);
   headerView.setNeedsDisplayInRect(rect);
 }
Esempio n. 6
0
 private void writeColumnOrder(final Tree tree) throws IOException {
   JSWriter writer = JSWriter.getWriterFor(tree);
   int[] values = tree.getColumnOrder();
   if (values.length > 0) {
     Integer[] newValue = new Integer[values.length];
     for (int i = 0; i < values.length; i++) {
       newValue[i] = new Integer(values[i]);
     }
     if (WidgetLCAUtil.hasChanged(tree, PROP_COLUMN_ORDER, newValue, new Integer[] {})) {
       writer.set(PROP_COLUMN_ORDER, "columnOrder", newValue, null);
     }
   }
 }
Esempio n. 7
0
 public static void packColumns(@NotNull Tree tree, boolean fit, @Nullable float[] ratios) {
   tree.setRedraw(false);
   try {
     // Check for disposed items
     // TODO: it looks like SWT error. Sometimes tree items are disposed and NPE is thrown from
     // column.pack
     for (TreeItem item : tree.getItems()) {
       if (item.isDisposed()) {
         return;
       }
     }
     int totalWidth = 0;
     final TreeColumn[] columns = tree.getColumns();
     for (TreeColumn column : columns) {
       column.pack();
       totalWidth += column.getWidth();
     }
     Rectangle clientArea = tree.getClientArea();
     if (clientArea.isEmpty()) {
       return;
     }
     if (fit) {
       int areaWidth = clientArea.width;
       if (tree.getVerticalBar() != null) {
         areaWidth -= tree.getVerticalBar().getSize().x;
       }
       if (totalWidth > areaWidth) {
         int extraSpace = totalWidth - areaWidth;
         for (TreeColumn tc : columns) {
           double ratio = (double) tc.getWidth() / totalWidth;
           tc.setWidth((int) (tc.getWidth() - extraSpace * ratio));
         }
       } else if (totalWidth < areaWidth) {
         float extraSpace = areaWidth - totalWidth;
         if (columns.length > 0) {
           if (ratios == null || ratios.length < columns.length) {
             extraSpace /= columns.length;
             extraSpace--;
             for (TreeColumn tc : columns) {
               tc.setWidth((int) (tc.getWidth() + extraSpace));
             }
           } else {
             for (int i = 0; i < columns.length; i++) {
               TreeColumn tc = columns[i];
               tc.setWidth((int) (tc.getWidth() + extraSpace * ratios[i]));
             }
           }
         }
       }
     }
   } finally {
     tree.setRedraw(true);
   }
 }
  /**
   * Causes the receiver to be resized to its preferred size. For a composite, this involves
   * computing the preferred size from its layout, if there is one.
   *
   * @exception SWTException
   *     <ul>
   *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
   *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
   *     </ul>
   */
  public void pack() {
    checkWidget();

    int width = 0;

    /* compute header width */
    NSTableHeaderCell headerCell = nsColumn.headerCell();
    NSSize size = headerCell.cellSize();
    width += Math.ceil(size.width);
    if (image != null) {
      NSSize imageSize = image.handle.size();
      width += Math.ceil(imageSize.width) + MARGIN;
    }
    if (parent.sortColumn == this && parent.sortDirection != SWT.NONE) {
      NSRect sortRect = headerCell.sortIndicatorRectForBounds(new NSRect());
      width += Math.ceil(sortRect.width + 2 * MARGIN);
    }

    /* compute item widths down column */
    GC gc = new GC(parent);
    width = Math.max(width, parent.calculateWidth(parent.items, parent.indexOf(this), gc, true));
    gc.dispose();
    setWidth(width);
  }
 public void setText(String string) {
   checkWidget();
   if (string == null) error(SWT.ERROR_NULL_ARGUMENT);
   super.setText(string);
   char[] buffer = new char[text.length()];
   text.getChars(0, buffer.length, buffer, 0);
   int length = fixMnemonic(buffer);
   displayText = new String(buffer, 0, length);
   NSString title = NSString.stringWith(displayText);
   nsColumn.headerCell().setTitle(title);
   NSTableHeaderView headerView = ((NSOutlineView) parent.view).headerView();
   if (headerView == null) return;
   int index = parent.indexOf(nsColumn);
   NSRect rect = headerView.headerRectOfColumn(index);
   headerView.setNeedsDisplayInRect(rect);
 }
Esempio n. 10
0
 private static void readSelection(final Tree tree) {
   String value = WidgetLCAUtil.readPropertyValue(tree, "selection");
   if (value != null) {
     String[] values = value.split(",");
     TreeItem[] selectedItems = new TreeItem[values.length];
     boolean validItemFound = false;
     for (int i = 0; i < values.length; i++) {
       selectedItems[i] = (TreeItem) WidgetUtil.find(tree, values[i]);
       if (selectedItems[i] != null) {
         validItemFound = true;
       }
     }
     if (!validItemFound) {
       selectedItems = new TreeItem[0];
     }
     tree.setSelection(selectedItems);
   }
 }
Esempio n. 11
0
 private static void readScrollPosition(final Tree tree) {
   String left = WidgetLCAUtil.readPropertyValue(tree, "scrollLeft");
   String top = WidgetLCAUtil.readPropertyValue(tree, "scrollTop");
   if (left != null && top != null) {
     Object adapter = tree.getAdapter(ITreeAdapter.class);
     final ITreeAdapter treeAdapter = (ITreeAdapter) adapter;
     final int newScrollLeft = parsePosition(left);
     final int newScrollTop = parsePosition(top);
     final int oldScrollTop = treeAdapter.getScrollTop();
     treeAdapter.setScrollLeft(newScrollLeft);
     treeAdapter.setScrollTop(newScrollTop);
     if (oldScrollTop != newScrollTop) {
       ProcessActionRunner.add(
           new Runnable() {
             public void run() {
               treeAdapter.checkAllData(tree);
             }
           });
     }
   }
 }
Esempio n. 12
0
 private static Boolean hasVScrollBar(final Tree tree) {
   Object adapter = tree.getAdapter(ITreeAdapter.class);
   ITreeAdapter treeAdapter = (ITreeAdapter) adapter;
   return Boolean.valueOf(treeAdapter.hasVScrollBar());
 }
Esempio n. 13
0
 private static Integer getScrollLeft(final Tree tree) {
   Object adapter = tree.getAdapter(ITreeAdapter.class);
   ITreeAdapter treeAdapter = (ITreeAdapter) adapter;
   return new Integer(treeAdapter.getScrollLeft());
 }
Esempio n. 14
0
 private static void writeHeaderVisible(final Tree tree) throws IOException {
   JSWriter writer = JSWriter.getWriterFor(tree);
   Boolean newValue = Boolean.valueOf(tree.getHeaderVisible());
   writer.set(PROP_HEADER_VISIBLE, "headerVisible", newValue, Boolean.FALSE);
 }
Esempio n. 15
0
  void drawInteriorWithFrame_inView(
      long /*int*/ id, long /*int*/ sel, NSRect cellRect, long /*int*/ view) {
    /*
     * Feature in Cocoa.  When the last column in a tree does not reach the
     * rightmost edge of the tree view, the cell that draws the rightmost-
     * column's header is also invoked to draw the header space between its
     * right edge and the tree's right edge.  If this case is detected then
     * nothing should be drawn.
     */
    int columnIndex = parent.indexOf(nsColumn);
    NSRect headerRect = parent.headerView.headerRectOfColumn(columnIndex);
    if (headerRect.x != cellRect.x || headerRect.width != cellRect.width) return;

    NSGraphicsContext context = NSGraphicsContext.currentContext();
    context.saveGraphicsState();

    int contentWidth = 0;
    NSSize stringSize = null, imageSize = null;
    NSAttributedString attrString = null;
    NSTableHeaderCell headerCell = nsColumn.headerCell();
    if (displayText != null) {
      Font font = Font.cocoa_new(display, headerCell.font());
      attrString =
          parent.createString(
              displayText, font, null, SWT.LEFT, false, (parent.state & DISABLED) == 0, false);
      stringSize = attrString.size();
      contentWidth += Math.ceil(stringSize.width);
      if (image != null) contentWidth += MARGIN; /* space between image and text */
    }
    if (image != null) {
      imageSize = image.handle.size();
      contentWidth += Math.ceil(imageSize.width);
    }

    if (parent.sortColumn == this && parent.sortDirection != SWT.NONE) {
      boolean ascending = parent.sortDirection == SWT.UP;
      headerCell.drawSortIndicatorWithFrame(cellRect, new NSView(view), ascending, 0);
      /* remove the arrow's space from the available drawing width */
      NSRect sortRect = headerCell.sortIndicatorRectForBounds(cellRect);
      cellRect.width = Math.max(0, sortRect.x - cellRect.x);
    }

    int drawX = 0;
    if ((style & SWT.CENTER) != 0) {
      drawX = (int) (cellRect.x + Math.max(MARGIN, ((cellRect.width - contentWidth) / 2)));
    } else if ((style & SWT.RIGHT) != 0) {
      drawX = (int) (cellRect.x + Math.max(MARGIN, cellRect.width - contentWidth - MARGIN));
    } else {
      drawX = (int) cellRect.x + MARGIN;
    }

    if (image != null) {
      NSRect destRect = new NSRect();
      destRect.x = drawX;
      destRect.y = cellRect.y;
      destRect.width = Math.min(imageSize.width, cellRect.width - 2 * MARGIN);
      destRect.height = Math.min(imageSize.height, cellRect.height);
      boolean isFlipped = new NSView(view).isFlipped();
      if (isFlipped) {
        context.saveGraphicsState();
        NSAffineTransform transform = NSAffineTransform.transform();
        transform.scaleXBy(1, -1);
        transform.translateXBy(0, -(destRect.height + 2 * destRect.y));
        transform.concat();
      }
      NSRect sourceRect = new NSRect();
      sourceRect.width = destRect.width;
      sourceRect.height = destRect.height;
      image.handle.drawInRect(destRect, sourceRect, OS.NSCompositeSourceOver, 1f);
      if (isFlipped) context.restoreGraphicsState();
      drawX += destRect.width;
    }

    if (displayText != null && displayText.length() > 0) {
      if (image != null) drawX += MARGIN; /* space between image and text */
      NSRect destRect = new NSRect();
      destRect.x = drawX;
      destRect.y = cellRect.y;
      destRect.width = Math.min(stringSize.width, cellRect.x + cellRect.width - MARGIN - drawX);
      destRect.height = Math.min(stringSize.height, cellRect.height);
      attrString.drawInRect(destRect);
    }
    if (attrString != null) attrString.release();

    context.restoreGraphicsState();
  }
Esempio n. 16
0
 private static void writeHeaderHeight(final Tree tree) throws IOException {
   JSWriter writer = JSWriter.getWriterFor(tree);
   Integer newValue = new Integer(tree.getHeaderHeight());
   writer.set(PROP_HEADER_HEIGHT, "headerHeight", newValue, null);
 }
Esempio n. 17
0
 void releaseWidget() {
   super.releaseWidget();
   if (parent.sortColumn == this) {
     parent.sortColumn = null;
   }
 }
Esempio n. 18
0
 void destroyWidget() {
   parent.destroyItem(this);
   releaseHandle();
 }
Esempio n. 19
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;
  }
Esempio n. 20
0
 /**
  * Constructs a new instance of this class given its parent (which must be a <code>Tree</code>)
  * and a style value describing its behavior and appearance. The item is added to the end of the
  * items maintained by its parent.
  *
  * <p>The style value is either one of the style constants defined in class <code>SWT</code> which
  * is applicable to instances of this class, or must be built by <em>bitwise OR</em>'ing together
  * (that is, using the <code>int</code> "|" operator) two or more of those <code>SWT</code> style
  * constants. The class description lists the style constants that are applicable to the class.
  * Style bits are also inherited from superclasses.
  *
  * @param parent a composite control which will be the parent of the new instance (cannot be null)
  * @param style the style of control to construct
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_NULL_ARGUMENT - if the parent is null
  *     </ul>
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  *       <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  *     </ul>
  *
  * @see SWT#LEFT
  * @see SWT#RIGHT
  * @see SWT#CENTER
  * @see Widget#checkSubclass
  * @see Widget#getStyle
  */
 public TreeColumn(Tree parent, int style) {
   super(parent, checkStyle(style));
   this.parent = parent;
   parent.createItem(this, parent.columnCount);
 }
Esempio n. 21
0
 /**
  * Sets the receiver's tool tip text to the argument, which may be null indicating that the
  * default tool tip for the control will be shown. For a control that has a default tool tip, such
  * as the Tree control on Windows, setting the tool tip text to an empty string replaces the
  * default, causing no tool tip text to be shown.
  *
  * <p>The mnemonic indicator (character '&amp;') is not displayed in a tool tip. To display a
  * single '&amp;' in the tool tip, the character '&amp;' can be escaped by doubling it in the
  * string.
  *
  * @param string the new tool tip text (or null)
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  *
  * @since 3.2
  */
 public void setToolTipText(String string) {
   checkWidget();
   toolTipText = string;
   parent.checkToolTip(this);
 }
Esempio n. 22
0
 /**
  * Constructs a new instance of this class given its parent (which must be a <code>Tree</code>), a
  * style value describing its behavior and appearance, and the index at which to place it in the
  * items maintained by its parent.
  *
  * <p>The style value is either one of the style constants defined in class <code>SWT</code> which
  * is applicable to instances of this class, or must be built by <em>bitwise OR</em>'ing together
  * (that is, using the <code>int</code> "|" operator) two or more of those <code>SWT</code> style
  * constants. The class description lists the style constants that are applicable to the class.
  * Style bits are also inherited from superclasses.
  *
  * <p>Note that due to a restriction on some platforms, the first column is always left aligned.
  *
  * @param parent a composite control which will be the parent of the new instance (cannot be null)
  * @param style the style of control to construct
  * @param index the zero-relative index to store the receiver in its parent
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_NULL_ARGUMENT - if the parent is null
  *       <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the
  *           parent (inclusive)
  *     </ul>
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  *       <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  *     </ul>
  *
  * @see SWT#LEFT
  * @see SWT#RIGHT
  * @see SWT#CENTER
  * @see Widget#checkSubclass
  * @see Widget#getStyle
  */
 public TreeColumn(Tree parent, int style, int index) {
   super(parent, checkStyle(style));
   this.parent = parent;
   parent.createItem(this, index);
 }
  @Override
  protected Control createControl(Composite parent) {
    Composite propertyComposite = new Composite(parent, SWT.BORDER);
    GridLayout layout = new GridLayout(1, false);
    layout.marginWidth = layout.marginHeight = 0;
    propertyComposite.setLayout(layout);
    if (mPage instanceof Page) {
      ((Page) mPage)
          .init(
              new IPageSite() {
                public void registerContextMenu(
                    String menuId, MenuManager menuManager, ISelectionProvider selectionProvider) {}

                public IActionBars getActionBars() {
                  return null;
                }

                public IWorkbenchPage getPage() {
                  return getWorkbenchWindow().getActivePage();
                }

                public ISelectionProvider getSelectionProvider() {
                  return null;
                }

                public Shell getShell() {
                  return getWorkbenchWindow().getShell();
                }

                public IWorkbenchWindow getWorkbenchWindow() {
                  return PlatformUI.getWorkbench().getActiveWorkbenchWindow();
                }

                public void setSelectionProvider(ISelectionProvider provider) {}

                @SuppressWarnings("unchecked")
                public Object getAdapter(Class adapter) {
                  return null;
                }

                @SuppressWarnings("unchecked")
                public Object getService(Class api) {
                  return null;
                }

                @SuppressWarnings("unchecked")
                public boolean hasService(Class api) {
                  return false;
                }
              });
    }
    if (mPage instanceof PropertySheetPage) {
      ((PropertySheetPage) mPage).setPropertySourceProvider(this);
    }
    mPage.createControl(propertyComposite);
    mPage.setActionBars(new DummyActionBars());
    final Control control = mPage.getControl();
    GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
    if (control instanceof Tree) {
      final Tree tree = (Tree) control;
      data.heightHint =
          tree.getItemHeight() * 13
              + (tree.getLinesVisible() ? 12 * tree.getGridLineWidth() : 0)
              + (tree.getHeaderVisible() ? tree.getHeaderHeight() : 0)
              + 2 * tree.getBorderWidth()
              + (tree.getHorizontalBar() != null ? tree.getHorizontalBar().getSize().x : 0);
      tree.addControlListener(
          new ControlAdapter() {
            @Override
            public void controlResized(ControlEvent e) {
              Rectangle area = tree.getClientArea();
              TreeColumn[] columns = tree.getColumns();
              if (area.width > 0) {
                columns[0].setWidth(area.width * 40 / 100);
                columns[1].setWidth(area.width - columns[0].getWidth() - 4);
              }
            }
          });
    } else if (control instanceof Composite) {
      control.addControlListener(
          new ControlAdapter() {
            @Override
            public void controlResized(ControlEvent e) {
              ((Composite) control).layout(true, true);
            }
          });
    }
    control.setLayoutData(data);
    ISelection selection;
    if (mCurrentWidget == null) {
      Collection<InstallOptionsModelTypeDef> typeDefs =
          InstallOptionsModel.INSTANCE.getControlTypeDefs();
      if (typeDefs.size() > 0) {
        InstallOptionsModelTypeDef typeDef = typeDefs.iterator().next();
        InstallOptionsElementFactory factory =
            InstallOptionsElementFactory.getFactory(typeDef.getType());
        mCurrentWidget = (InstallOptionsWidget) factory.getNewObject();
        mDialog.addChild(mCurrentWidget);
      }
    }

    if (mCurrentWidget != null) {
      mCurrentWidget.addModelCommandListener(InstallOptionsWidgetEditorDialog.this);
      mCurrentWidget.addPropertyChangeListener(InstallOptionsWidgetEditorDialog.this);
      if (mCurrentWidget.getParent() != null) {
        mCurrentWidget.getParent().addPropertyChangeListener(InstallOptionsWidgetEditorDialog.this);
      }
      selection = new StructuredSelection(mCurrentWidget);
    } else {
      selection = StructuredSelection.EMPTY;
    }

    mPage.selectionChanged(null, selection);
    PlatformUI.getWorkbench().getHelpSystem().setHelp(mPage.getControl(), HELP_CONTEXT);
    PlatformUI.getWorkbench().getHelpSystem().setHelp(propertyComposite, HELP_CONTEXT);

    return propertyComposite;
  }