예제 #1
0
  public void appendText(String text, long type) {
    if (m_Text.isDisposed()) return;

    // This is needed because the text control (on Windows) stores newlines
    // as \r\n and selections and character counts will get out of synch if
    // we
    // work in the text control but reason about the text and they have
    // different newlines.
    // (We still use \n everywhere else as the newline marker because that's
    // what Soar uses)
    text = text.replaceAll(AbstractView.kLineSeparator, AbstractView.kSystemLineSeparator);

    boolean show = true;
    int recordIndex = -1;

    if (m_FilteringEnabled) {
      // Record the text in our master filter document.
      // Also decide if we should show this particular line of text.
      recordIndex = m_FilterDoc.addRecord(text, false, type);
      show = m_FilterDoc.show(type);
    }

    if (show) {
      appendTextInternal(text, false, recordIndex);

      // Decide if we have caused the window to scroll or not
      if (m_LastTopIndex != m_Text.getTopIndex()) {
        scrolled();
        m_LastTopIndex = m_Text.getTopIndex();
      }
    }
  }
예제 #2
0
  /**
   * Runs a runnable, which executes some code. The top visible line number of the text field is
   * remembered, and after the runnable has finished, the top visible line is restored is set to the
   * remembered number.
   *
   * @param runnable
   */
  protected void doTxfieldActionPreservingVisibleLines(final Runnable runnable, Text textfield) {
    final Display display = textfield.getDisplay();
    final int topIndex = textfield.getTopIndex();
    runnable.run();

    new Thread() {
      @Override
      public void run() {
        try {
          Thread.sleep(20);
        } catch (InterruptedException e) {
          LogUtil.logError(e);
        }
        Runnable r =
            new Runnable() {
              @Override
              public void run() {
                txtInputText.setTopIndex(topIndex);
              }
            };

        display.syncExec(r);
      };
    }.start();
  }
예제 #3
0
  // Returns the line we clicked on based on mouse coordinates
  public int getLine(int mouseY) {
    int topLine = m_Text.getTopIndex();
    int lineHeight = m_Text.getLineHeight();
    int screenLine = mouseY / lineHeight;
    int line = topLine + screenLine;

    if (line > m_Text.getLineCount()) return -1;

    return line;
  }
예제 #4
0
  /** Expand/contract all blocks currently on screen */
  public void expandPage(boolean state) {
    // Get all the information about which part of the text window is
    // visible
    int topLine = m_Text.getTopIndex();
    int lineHeight = m_Text.getLineHeight();
    int visibleLines = m_Text.getClientArea().height / lineHeight;
    int lastLine = Math.min(m_Text.getLineCount(), m_Text.getTopIndex() + visibleLines);

    boolean atBottom = (lastLine == m_Text.getLineCount());

    // Start with the first block that starts at topLine or includes
    // topLine.
    Block topBlock = m_FoldingDoc.getBlockByLineNumber(topLine);
    Block bottomBlock = m_FoldingDoc.getBlockByLineNumber(lastLine);

    if (topBlock == null) return;

    // Stop redrawing while we expand/collapse everything then turn it back
    // on
    setRedraw(false);

    // If the lastLine is after the bottom block, use the last block in the
    // document
    if (bottomBlock == null)
      bottomBlock = m_FoldingDoc.getBlock(m_FoldingDoc.getNumberBlocks() - 1);

    int topIndex = topBlock.getIndex();
    int bottomIndex = bottomBlock.getIndex();

    for (int i = topIndex; i <= bottomIndex; i++) {
      Block block = m_FoldingDoc.getBlock(i);
      m_FoldingDoc.expandBlock(block, state);
    }

    // If the selection was set to the bottom before we expanded make sure
    // it stays there after the expansion.
    if (state && atBottom) scrollBottom();

    // Redraw everything
    setRedraw(true);
  }
예제 #5
0
  protected void iconBarMouseClick(MouseEvent e) {
    // Make sure the text control is properly initialized
    if (m_Text.getLineHeight() == 0) return;

    int topLine = m_Text.getTopIndex();
    int lineHeight = m_Text.getLineHeight();

    int line = (e.y / lineHeight) + topLine;

    // By using the "getBlockByLineNumber" method we get either the start
    // of a block or the block that encloses this line.
    // This means that clicking on the line beneath an expanded block will
    // cause it to collapse. I think that's a nice feature, but if we'd
    // rather
    // not have that happen switch this to getBlockStartsAtLineNumber() and
    // only clicks right on the icon will cause behavior.
    Block block = m_FoldingDoc.getBlockByLineNumber(line);

    if (block == null) return;

    m_FoldingDoc.expandBlock(block, !block.isExpanded());
    m_IconBar.redraw();
  }
예제 #6
0
  public FoldingText(Composite parent) {
    m_Container = new Composite(parent, 0);

    // The icon bar is used to paint the "+" signs. It is double-buffered or
    // we'll get a little flicker effect because we repaint it on a timer.
    m_IconBar = new Canvas(m_Container, SWT.DOUBLE_BUFFERED);
    m_Text = new Text(m_Container, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY);

    m_DrawingDisabled = false;

    GridLayout layout = new GridLayout();
    layout.numColumns = 2;
    m_Container.setLayout(layout);

    GridData data1 = new GridData(GridData.FILL_VERTICAL);
    data1.widthHint = 13;
    m_IconBar.setLayoutData(data1);

    GridData data2 = new GridData(GridData.FILL_BOTH);
    m_Text.setLayoutData(data2);

    m_IconBar.addPaintListener(
        new PaintListener() {
          public void paintControl(PaintEvent e) {
            paintIcons(e);
          }
        });
    m_IconBar.setBackground(m_IconBar.getDisplay().getSystemColor(SWT.COLOR_WHITE));

    m_IconBar.addMouseListener(
        new MouseAdapter() {
          public void mouseUp(MouseEvent e) {
            iconBarMouseClick(e);
          }
        });

    // Think we'll need this so we update the icons while we're scrolling
    m_Text
        .getVerticalBar()
        .addSelectionListener(
            new SelectionAdapter() {
              public void widgetSelected(SelectionEvent e) {
                scrolled();
              }
            });

    // The user can trigger a scroll in the text window in other ways than
    // grabbing the scroll bar thumb and moving it so we
    // need to detect those too.
    Listener listener =
        new Listener() {
          int lastIndex = m_Text.getTopIndex();

          public void handleEvent(Event e) {
            int index = m_Text.getTopIndex();
            if (index != lastIndex) {
              lastIndex = index;
              scrolled();
            }
          }
        };

    // NOTE: Only detects scrolling by the user and not quite correct if you
    // drag out of the window
    // (This code came from the SWT web site itself)
    m_Text.addListener(SWT.MouseDown, listener);
    m_Text.addListener(SWT.MouseMove, listener);
    m_Text.addListener(SWT.MouseUp, listener);
    m_Text.addListener(SWT.KeyDown, listener);
    m_Text.addListener(SWT.KeyUp, listener);
    m_Text.addListener(SWT.Resize, listener);

    // Because the above tests aren't always correct we'll also use a timer
    // to redraw the icon bar
    // at a slow rate. This ensures the icons are correct after the delay
    // has passed in all cases.
    // (We're using a slow timer rather than calling redraw after each line
    // of text is added, for instance,
    // to boost overall performance). In practice this timer is correcting a
    // minor cosmetic issue so it's
    // not worth trading real performance for.
    periodicRepaint(500);

    m_LastTopIndex = m_Text.getTopIndex();
  }
예제 #7
0
  protected void paintIcons(PaintEvent e) {
    // Check if we've turned off redraws
    if (m_DrawingDisabled) return;

    GC gc = e.gc;

    Rectangle client = m_IconBar.getClientArea();

    // Make sure the text control is properly initialized
    if (m_Text.getLineHeight() == 0) return;

    // Get all the information about which part of the text window is
    // visible
    int topLine = m_Text.getTopIndex();
    int lineHeight = m_Text.getLineHeight();
    int visibleLines = m_Text.getClientArea().height / lineHeight;
    int lastLine = Math.min(m_Text.getLineCount(), m_Text.getTopIndex() + visibleLines);

    // Start with the first block that starts at topLine or includes
    // topLine.
    Block topBlock = m_FoldingDoc.getBlockByLineNumber(topLine);
    int blockCount = m_FoldingDoc.getNumberBlocks();

    if (topBlock == null) return;

    int blockIndex = topBlock.getIndex();

    int outerSize = 9;
    int innerSize = 6;
    int offset = (outerSize - innerSize) / 2 + 1;

    Color gray = m_IconBar.getDisplay().getSystemColor(SWT.COLOR_GRAY);
    Color black = m_IconBar.getDisplay().getSystemColor(SWT.COLOR_BLACK);

    // Go through each block in turn until we're off the bottom of the
    // screen
    // or at the end of the list of blocks drawing icons
    while (blockIndex != -1 && blockIndex < blockCount) {
      Block block = m_FoldingDoc.getBlock(blockIndex);

      int line = block.getStart();

      // Once we drop off the bottom of the screen we're done
      if (line >= lastLine) break;

      int pos = line - topLine;
      int y = pos * lineHeight + (lineHeight / 2) - (outerSize / 2) - 1;
      int x = 1;

      boolean expanded = block.isExpanded();

      if (block.canExpand()) {
        gc.drawRectangle(x, y, x + outerSize, x + outerSize);

        // Start with a - sign
        int y1 = y + 1 + (outerSize / 2);
        gc.drawLine(x + offset, y1, x + offset + innerSize, y1);

        if (!expanded) {
          // If not expanded turn the - into a +
          int x1 = x + 1 + (outerSize / 2);
          gc.drawLine(x1, y + offset, x1, y + offset + innerSize);
        } else {
          // If expanded draw a line to show what is in the expanded
          // area
          gc.setForeground(gray);
          int x1 = x + 1 + (outerSize / 2);
          int yTop = y + outerSize + 2;
          int yBottom = y + ((block.getSize() - 1) * lineHeight) + (outerSize / 2);
          gc.drawLine(x1, yTop, x1, yBottom);
          gc.drawLine(x1, yBottom, client.width - 1, yBottom);
          gc.setForeground(black);
        }
      }
      blockIndex++;
    }
  }
예제 #8
0
  protected void appendSubTextInternal(String text, boolean autoExpand, int recordIndex) {
    Block last = m_FoldingDoc.m_LastBlock;

    if (last == null) {
      // This is an odd situation where we're adding subtext but have no
      // supertext to append to.
      // It probably will never occur, but if it does we'll add a blank
      // super text block just
      // to get us going.
      last = new Block(true, recordIndex);
      last.appendLine("");
      last.setExpand(autoExpand);
      m_FoldingDoc.addBlock(last);
      appendTextToWidget(m_Text, "");
      m_IconBar.redraw();
    }

    if (!last.canExpand()) {
      // Need to remove the last line from the block and move it to a new
      // block
      // which can expand and then proceed with the addition to this new
      // block
      // Thus we ensure that "canExpand" items have at least one child.
      int size = last.getSize();

      if (size == 1) {
        // If the last block only contains exactly one line we can
        // convert it safely
        // to a block which does expand. This way we also preserve the
        // "all blocks contain
        // at least one line" rule which makes the code simpler.
        last.setCanExpand(true);
        last.setExpand(autoExpand);
      } else if (size > 1) {
        // NOTE: Blocks should always have at least one line so these
        // calls
        // should never fail (if they do it's a programming error
        // somewhere else that
        // allowed an empty block to be created).
        String lastLine = last.getLastLine();
        last.removeLastLine();

        last = new Block(true, recordIndex);
        last.appendLine(lastLine);
        last.setExpand(autoExpand);
        m_FoldingDoc.addBlock(last);
      } else if (size == 0) {
        throw new IllegalStateException("Last block should not be empty");
      }

      // There's no change to the text sprite (because the line is just
      // moved between logical blocks)
      // but we will need to draw the icons to show there's a new block.
      m_IconBar.redraw();
    }

    last.appendLine(text);

    if (last.isExpanded()) {
      appendTextToWidget(m_Text, text);

      // Decide if we have caused the window to scroll or not
      if (!autoExpand && (m_LastTopIndex != m_Text.getTopIndex())) {
        scrolled();
        m_LastTopIndex = m_Text.getTopIndex();
      }
    }
  }