Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[platform-ui-dev] a note about status line contributions

In build 20011127 text editors derived from AbstractTextEditor and
associated with an instance of BasicTextEditorActionContributor show status
information in the window's status bar. By default the status information
consists of three status fields showing the cursor position, the input
mode, and whether the editor's input is read only or writable.

While implementing this feature I found a few issues I'd like to bring up.
It seems to me that in order to achieve a correctly working status line
contribution a rather fond understanding of some of the workbench's and
JFace internals is required. One reason for that might be that I took the
wrong path to implement things. If so please let me know how to make it
right.


BasicTextEditorActionContributor extends EditorActionBarContributor
overriding contributeToStatusLine as follows:

public void contributeToStatusLine(IStatusLineManager statusLineManager) {
     super.contributeToStatusLine(statusLineManager);
     for (int i= 0; i < STATUSFIELDS.length; i++)
          statusLineManager.add((IContributionItem)
fStatusFields.get(STATUSFIELDS[i]));
}

Issue 1:

- I'd expect contributeToStatusLine to be called every time the first
instance of a particular editor type is created. Indeed it is called for
each newly created editor. In order to avoid contribution items per editor,
it is necessary to contribute the same contribution items on every call.
This way the status line manager recognizes that they are already there and
avoids duplications.
- That the contributed items must be the same can easily be overlooked and
so I did.

As the status line manager can be configured with contribution items I
implemented a StatusLineContributionItem. The code snippet below is derived
from the working code. There are the following issues:

Issue 2:

- The label added to the widget hierarchy needs to have its data pointer
set the contributing item. If not, the contribution item is never removed
from the status line. The algorithm that determines which items are to be
added and removed relies on a "valid" data pointer.
- That the contributed widget must have its data pointer being set to the
contribution item can easily be overlooked and so I did.

Issue 3:

- The label added to the widget  hierarchy is a custom made widget
redefining computeSize. Explicitly setting the size of the label does not
have any effect. StatusLineLayout always passes SWT.DEFAULT to the
computeSize method of the contributed widgets which usually causes them to
ignore their size settings. I am not aware of another way to ensure a
certain width of the status line contribution rather then defining a custom
widget.
- That the size hints are ignored can easily be overlooked and so I did.

Issue 4:

- As the custom widget ensures a fixed width, it also has to know the
height. The information about which height is expected can only be found in
the code.


public class StatusLineContributionItem extends ContributionItem implements
IStatusField {


     static class StatusLineLabel extends CLabel {

          private Point fFixedSize;

          public StatusLineLabel(Composite parent, int style) {
               super(parent, style);
               fFixedSize= new Point(<computed width>, 10);
          }

          public Point computeSize(int wHint, int hHint, boolean changed) {
               return fFixedSize;
          }
     };

     private String fText;
     private Image fImage;
     private StatusLineLabel fLabel;

     /**
      * Creates a new item with the given id.
      *
      * @param id the item's id
      */
     StatusLineContributionItem(String id) {
          super(id);
     }

     <snip>

     /*
      * @see IContributionItem#fill(Composite)
      */
     public void fill(Composite parent) {
          fLabel= new StatusLineLabel(parent, SWT.SHADOW_IN);
          fLabel.setData(this);

          if (fText != null)
               fLabel.setText(fText);

          if (fImage != null)
               fLabel.setImage(fImage);
     }
}

Kai



Back to the top