public void expandBlock(Block block, boolean state) { if (block.isExpanded() == state || !block.canExpand() || block.getSize() == 1) return; Point range = getBlockSelectionRange(block); int delta = 0; m_FoldingText.m_Text.setSelection(range); if (state) { // Expanding m_FoldingText.m_Text.insert(block.getAll()); delta = block.getSize() - 1; } else { m_FoldingText.m_Text.insert(block.getFirst()); delta = 1 - block.getSize(); } // Set the selection back to the top of the range (it defaults to // the bottom) // so we see the top of the newly expanded block if it's long m_FoldingText.m_Text.setSelection(range.x); // Update the remaining block position info int size = getNumberBlocks(); for (int b = block.getIndex() + 1; b < size; b++) { Block update = getBlock(b); update.setStart(update.getStart() + delta); } block.setExpand(state); }
// This method can be called either as a result of new input coming from // outside // or because of a change to a filter as we re-process the old information. private void appendTextInternal(String text, boolean autoExpand, int recordIndex) { Block last = m_FoldingDoc.m_LastBlock; if (last == null || last.canExpand()) { // We create blocks that can't fold to hold top level text lines last = new Block(false, recordIndex); m_FoldingDoc.addBlock(last); } last.appendLine(text); last.setExpand(autoExpand); appendTextToWidget(m_Text, text); }
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++; } }
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(); } } }