From: <al...@us...> - 2008-11-19 07:02:33
|
Revision: 1894 http://omegat.svn.sourceforge.net/omegat/?rev=1894&view=rev Author: alex73 Date: 2008-11-19 07:02:28 +0000 (Wed, 19 Nov 2008) Log Message: ----------- Changes for RTL writing(not clean and not finished yet) Modified Paths: -------------- branches/prototypes/new-editor/src/org/omegat/gui/editor/OmDocument.java branches/prototypes/new-editor/src/org/omegat/gui/editor/OmEditorKit.java branches/prototypes/new-editor/src/org/omegat/gui/editor/SegmentElementsDescription.java Added Paths: ----------- branches/prototypes/new-editor/src/org/omegat/gui/editor/SegmentMarkView.java Modified: branches/prototypes/new-editor/src/org/omegat/gui/editor/OmDocument.java =================================================================== --- branches/prototypes/new-editor/src/org/omegat/gui/editor/OmDocument.java 2008-11-18 19:35:31 UTC (rev 1893) +++ branches/prototypes/new-editor/src/org/omegat/gui/editor/OmDocument.java 2008-11-19 07:02:28 UTC (rev 1894) @@ -26,17 +26,18 @@ import java.awt.Color; import java.awt.Font; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; +import java.awt.font.TextAttribute; import java.util.Enumeration; import javax.swing.text.AbstractDocument; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; +import javax.swing.text.BoxView; +import javax.swing.text.CompositeView; import javax.swing.text.EditorKit; import javax.swing.text.Element; import javax.swing.text.Position; +import javax.swing.text.SimpleAttributeSet; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; @@ -44,6 +45,7 @@ import javax.swing.text.View; import org.omegat.core.data.SourceTextEntry; +import org.omegat.util.gui.ExtendedLabelView; import org.omegat.util.gui.UIThreadsUtil; /** @@ -60,7 +62,7 @@ * * @author Alex Buloichik (ale...@gm...) */ -class OmDocument extends AbstractDocument implements StyledDocument { +public class OmDocument extends AbstractDocument implements StyledDocument { /** Editor controller. */ protected final EditorController controller; @@ -121,6 +123,8 @@ } root.replace(0, 0, segments); + omFixBidi(); + return segments; } finally { writeUnlock(); @@ -227,11 +231,33 @@ View mainDocView = controller.editor.getUI().getRootView( controller.editor).getView(0); View segmentView = mainDocView.getView(segmentIndex); - View[] nv = new View[seg.getElementCount()]; - for (int i = 0; i < nv.length; i++) { - nv[i] = kit.getViewFactory().create(seg.getElement(i)); - } - segmentView.replace(0, segmentView.getViewCount(), nv); + // View[] nv = new View[seg.getElementCount()]; + // for (int i = 0; i < nv.length; i++) { + // nv[i] = kit.getViewFactory().create(seg.getElement(i)); + // + // // View[] cv=new View[seg.getElement(i).getElementCount()]; + // // for(int j=0;j<cv.length;j++) { + // // + // cv[j]=kit.getViewFactory().create(seg.getElement(i).getElement(j)); + // // } + // // nv[i].replace(0, 0, cv); + // } + // segmentView.replace(0, segmentView.getViewCount(), nv); + + // remove old children + segmentView.removeAll(); + // required to call 'loadChildren' +// ((BoxView) segmentView).layoutChanged(View.X_AXIS); +// ((BoxView) segmentView).layoutChanged(View.Y_AXIS); + segmentView.setParent(mainDocView); + + +// View[] nv = new View[seg.getElementCount()]; +// for (int i = 0; i < nv.length; i++) { +// nv[i] = kit.getViewFactory().create(seg.getElement(i)); +// } +// segmentView.replace(0, segmentView.getViewCount(), nv); + } /** @@ -289,18 +315,53 @@ UIThreadsUtil.mustBeSwingThread(); super.insertUpdate(chng, attr); + // if( getProperty("i18n").equals( Boolean.TRUE ) ) + // omUpdateBidi( chng ); try { int segmentIndex = root.getElementIndex(chng.getOffset()); + dump(); // we have to rebuild segment each time, because we need to check // spelling, and possible rebuild paragraphs rebuildElementsForSegment(chng, segmentIndex); + dump(); } catch (BadLocationException ex) { throw new RuntimeException(ex); } } /** + * Fix bidi values for full document. + */ + protected void omFixBidi() { + if (true) return;//TODO debug + System.out.println("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"); + + // initialize bidi elements + BranchElement bidiRoot = (BranchElement) getBidiRootElement(); + LeafElement[] segsBidi = new LeafElement[root.getElementCount()]; + for (int i = 0; i < segsBidi.length; i++) { + Element seg = root.getElement(i); + segsBidi[i] = new LeafElement(bidiRoot, new SimpleAttributeSet(), + seg.getStartOffset(), seg.getEndOffset()); + segsBidi[i].addAttribute(StyleConstants.BidiLevel, 2); + } + bidiRoot.replace(0, bidiRoot.getElementCount(), segsBidi); + dump(); + System.out.println("yyyyyyyyyyyyyyyyyy"); + } + +// protected void setDirection(Boolean dir) { +// getDocumentProperties().put(TextAttribute.RUN_DIRECTION, dir); +// writeLock(); +// try { +// omFixBidi(); +// } finally { +// writeUnlock(); +// } +// } + + /** * Rebuild elements fro specified segment after user's change. * * @param chng @@ -311,7 +372,7 @@ */ private void rebuildElementsForSegment(DefaultDocumentEvent chng, int segmentIndex) throws BadLocationException { - try { + try {System.out.println("rebuild"); writeLock(); OmElementSegment segElement; @@ -334,10 +395,20 @@ Element[] added = desc.createElementsForSegment(this, segElement, fullSegmentText, offsetFromDocumentBegin); + // fix bidi for segment + BranchElement bidiRoot = (BranchElement) getBidiRootElement(); + LeafElement segBidi = new LeafElement(bidiRoot, + new SimpleAttributeSet(), segElement.getStartOffset(), + segElement.getEndOffset()); + segBidi.addAttribute(StyleConstants.BidiLevel, 0); + bidiRoot.replace(segmentIndex, 1, new Element[] { segBidi }); + + // set elements to document replaceSegmentElements(segmentIndex, (OmEditorKit) controller.editor.getEditorKit(), added); segElement.replace(0, segElement.getElementCount(), added); + } finally { writeUnlock(); } @@ -566,6 +637,18 @@ OmContent.POSITION_TYPE.AFTER_EDITABLE); } + @Override + public void addAttribute(Object name, Object value) { + // TODO debug + super.addAttribute(name, value); + } + + @Override + public void addAttributes(AttributeSet attr) { + // TODO debug + super.addAttributes(attr); + } + public String getName() { return "text"; } @@ -604,6 +687,114 @@ } /** + * Implement own TextElement. We can't use standard LeafElement, because we + * want to create "before/inside/after" positions. + */ + public class OmElementSegmentMark extends AbstractElement { + protected final Position p0, p1; + + public OmElementSegmentMark(Element parent, AttributeSet a, int offs0, + int offs1, OmContent.POSITION_TYPE positionType) { + super(parent, a); + p0 = getData().createPosition(offs0, positionType); + p1 = getData().createPosition(offs1, positionType); + } + + public OmElementSegmentMark(Element parent, AttributeSet a, int offs) { + super(parent, a); + p0 = getData().createPosition(offs, + OmContent.POSITION_TYPE.BEFORE_EDITABLE); + p1 = getData().createPosition(offs, + OmContent.POSITION_TYPE.AFTER_EDITABLE); + } + + @Override + public void addAttribute(Object name, Object value) { + // TODO debug + super.addAttribute(name, value); + } + + @Override + public void addAttributes(AttributeSet attr) { + // TODO debug + super.addAttributes(attr); + } + + public String getName() { + return "segmentmark"; + } + + public int getStartOffset() { + return p0.getOffset(); + } + + public int getEndOffset() { + return p1.getOffset(); + } + + public int getElementIndex(int pos) { + return -1; + } + + public Element getElement(int index) { + return null; + } + + public int getElementCount() { + return 0; + } + + public boolean isLeaf() { + return true; + } + + public boolean getAllowsChildren() { + return false; + } + + public Enumeration<?> children() { + return null; + } + } + + protected void dump() { + if (true) + return; + System.out.println("======================================="); + for (Element el : getRootElements()) { + dump(el, 0); + } + System.out.println("===== view: ======="); + dump(controller.editor.getUI().getRootView(controller.editor) + .getView(0), 0); + } + + protected static void dump(View v, int indentAmount) { + if (v == null) + return; + + indent(indentAmount); + System.out.println("Class: " + v.getClass().getCanonicalName() + " " + + v); + if (v instanceof BoxView) { + BoxView bv = (BoxView) v; + indent(indentAmount); + System.out + .println(" w:" + bv.getWidth() + " h:" + bv.getHeight()); + } + if (v instanceof ExtendedLabelView) { + ExtendedLabelView elv = (ExtendedLabelView) v; + dump(elv.getElement(), indentAmount + 2); + } + if (v instanceof CompositeView) { + CompositeView cv = (CompositeView) v; + for (int i = 0; i < cv.getViewCount(); i++) { + dump(cv.getView(i), indentAmount + 2); + } + } + } + + /** * Method for debugging purpose only. It shows element better than standard * Element.dump method. * @@ -611,40 +802,39 @@ * element * @param indentAmount */ - protected static void dump(AbstractElement el, int indentAmount) { - PrintWriter out; - try { - out = new PrintWriter( - new OutputStreamWriter(System.out, "JavaEsc"), true); - } catch (UnsupportedEncodingException e) { - out = new PrintWriter(System.out, true); - } - indent(out, indentAmount); + public static void dump(Element ell, int indentAmount) { + AbstractElement el = (AbstractElement) ell; + indent(indentAmount); if (el.getName() == null) { - out.print("<??"); + System.out.print("<??"); } else { - out.print("<" + el.getName()); + System.out.print("<" + el.getName()); } if (el.getAttributeCount() > 0) { - out.println(""); + System.out.println(); // dump the attributes Enumeration<?> names = el.getAttributeNames(); while (names.hasMoreElements()) { Object name = names.nextElement(); - indent(out, indentAmount + 1); - out.println(name + "=" + el.getAttribute(name)); + indent(indentAmount + 1); + System.out.println(name + "=" + el.getAttribute(name)); } - indent(out, indentAmount); + indent(indentAmount); } - out.print(">"); + System.out.print(">"); if (el.isLeaf()) { - indent(out, indentAmount + 1); + indent(indentAmount + 1); - Position p0 = ((OmElementText) el).p0; - Position p1 = ((OmElementText) el).p1; + if (el instanceof OmElementText) { + Position p0 = ((OmElementText) el).p0; + Position p1 = ((OmElementText) el).p1; - out.print("[" + p0 + "," + p1 + "]"); + System.out.print("[" + p0 + "," + p1 + "]"); + } else { + System.out.print("[" + el.getStartOffset() + "," + + el.getEndOffset() + "]"); + } Content c = ((OmDocument) el.getDocument()).getContent(); try { String contentStr = c.getString(el.getStartOffset(), el @@ -654,13 +844,13 @@ contentStr = contentStr.substring(0, 40) + "..."; } contentStr = contentStr.replace("\n", "'\\n'"); - out.println("[" + contentStr + "]"); - } catch (BadLocationException e) { - ; + System.out.println("[" + contentStr + "]"); + } catch (Exception e) { + System.out.println("<unk>"); } } else { - out.println(); + System.out.println(); int n = el.getElementCount(); for (int i = 0; i < n; i++) { AbstractElement e = (AbstractElement) el.getElement(i); @@ -669,9 +859,9 @@ } } - private static final void indent(PrintWriter out, int n) { + private static final void indent(int n) { for (int i = 0; i < n; i++) { - out.print(" "); + System.out.print(" "); } } } Modified: branches/prototypes/new-editor/src/org/omegat/gui/editor/OmEditorKit.java =================================================================== --- branches/prototypes/new-editor/src/org/omegat/gui/editor/OmEditorKit.java 2008-11-18 19:35:31 UTC (rev 1893) +++ branches/prototypes/new-editor/src/org/omegat/gui/editor/OmEditorKit.java 2008-11-19 07:02:28 UTC (rev 1894) @@ -68,6 +68,8 @@ return new ParagraphView(elem); } else if (kind.equals("segment")) { return new BoxView(elem, View.Y_AXIS); + } else if (kind.equals("segmentmark")) { + return new SegmentMarkView(elem); } } return null; Modified: branches/prototypes/new-editor/src/org/omegat/gui/editor/SegmentElementsDescription.java =================================================================== --- branches/prototypes/new-editor/src/org/omegat/gui/editor/SegmentElementsDescription.java 2008-11-18 19:35:31 UTC (rev 1893) +++ branches/prototypes/new-editor/src/org/omegat/gui/editor/SegmentElementsDescription.java 2008-11-19 07:02:28 UTC (rev 1894) @@ -24,12 +24,14 @@ package org.omegat.gui.editor; +import java.awt.font.TextAttribute; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import javax.swing.text.AttributeSet; import javax.swing.text.Element; +import javax.swing.text.SimpleAttributeSet; import org.omegat.core.Core; import org.omegat.core.data.SourceTextEntry; @@ -209,8 +211,7 @@ List<OmDocument.OmElementParagraph> paragraphElements = new ArrayList<OmDocument.OmElementParagraph>( 32); - List<OmDocument.OmElementText> textElements = new ArrayList<OmDocument.OmElementText>( - 64); + List<Element> textElements = new ArrayList<Element>(64); /** * Create SegmentElement's child elements by segment description. @@ -228,27 +229,33 @@ Element[] createElementsForSegment(OmDocument doc, OmElementSegment segElement, String text, int offsetFromDocumentBegin) { - paragraphElements.add(doc.new OmElementParagraph(segElement, null)); + SimpleAttributeSet a = new SimpleAttributeSet();// TODO + a.addAttribute(TextAttribute.RUN_DIRECTION, + TextAttribute.RUN_DIRECTION_LTR); + paragraphElements.add(doc.new OmElementParagraph(segElement, a)); + // add sources addLines(segElement, ATTR_SOURCE, text.substring(0, translationBeginTagStart), offsetFromDocumentBegin, false, OmContent.POSITION_TYPE.BEFORE_EDITABLE); // add <segment 0000> - addLines(segElement, ATTR_SEGMENT_MARK, text.substring( + addSegmentMark(segElement, ATTR_SEGMENT_MARK, text.substring( translationBeginTagStart, translationBeginTagEnd), offsetFromDocumentBegin + translationBeginTagStart, false, OmContent.POSITION_TYPE.BEFORE_EDITABLE); + // add translation addLines(segElement, translationAttrs, text.substring( translationBeginTagEnd, translationEndTagStart), offsetFromDocumentBegin + translationBeginTagEnd, needToCheckSpelling, OmContent.POSITION_TYPE.INSIDE_EDITABLE); // add <end segment> - addLines(segElement, ATTR_SEGMENT_MARK, text.substring( + addSegmentMark(segElement, ATTR_SEGMENT_MARK, text.substring( translationEndTagStart, translationEndTagEnd), offsetFromDocumentBegin + translationEndTagStart, false, OmContent.POSITION_TYPE.AFTER_EDITABLE); + // add <new lines segments separator> addLines(segElement, null, text.substring(translationEndTagEnd), offsetFromDocumentBegin + translationEndTagEnd, false, @@ -258,6 +265,14 @@ return paragraphElements.toArray(new Element[paragraphElements.size()]); } + private void addSegmentMark(OmDocument.OmElementSegment section, + AttributeSet attrs, String partText, int offsetFromDocumentBegin, + boolean needSpellCheck, OmContent.POSITION_TYPE positionType) { + textElements.add(doc.new OmElementSegmentMark(last(paragraphElements), + attrs, offsetFromDocumentBegin, offsetFromDocumentBegin + + partText.length(), positionType)); + } + /** * Add lines elements. * @@ -292,7 +307,10 @@ textElements.toArray(new Element[textElements.size()])); textElements.clear(); - paragraphElements.add(doc.new OmElementParagraph(section, null)); + SimpleAttributeSet a = new SimpleAttributeSet();// TODO + a.addAttribute(TextAttribute.RUN_DIRECTION, + TextAttribute.RUN_DIRECTION_LTR); + paragraphElements.add(doc.new OmElementParagraph(section, a)); prevPos = pos + 1; } addLine(attrs, partText.substring(prevPos), offsetFromDocumentBegin @@ -316,7 +334,7 @@ private void addLine(AttributeSet attrs, String partText, int offsetFromDocumentBegin, boolean needSpellCheck, OmContent.POSITION_TYPE positionType) { - if (partText.length()==0) { + if (partText.length() == 0) { return; } if (!needSpellCheck) { Added: branches/prototypes/new-editor/src/org/omegat/gui/editor/SegmentMarkView.java =================================================================== --- branches/prototypes/new-editor/src/org/omegat/gui/editor/SegmentMarkView.java (rev 0) +++ branches/prototypes/new-editor/src/org/omegat/gui/editor/SegmentMarkView.java 2008-11-19 07:02:28 UTC (rev 1894) @@ -0,0 +1,193 @@ +/************************************************************************** + OmegaT - Computer Assisted Translation (CAT) tool + with fuzzy matching, translation memory, keyword search, + glossaries, and translation leveraging into updated projects. + + Copyright (C) 2008 Alex Buloichik + Home page: http://www.omegat.org/ + Support center: http://groups.yahoo.com/group/OmegaT/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + **************************************************************************/ + +package org.omegat.gui.editor; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.Shape; + +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.Element; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; +import javax.swing.text.View; +import javax.swing.text.Position.Bias; + +/** + * Class for display segmentation marks. It better to paint marks by own + * component, because we will not have problems with RTL writing. + * + * @author Alexander_Buloichik + */ +public class SegmentMarkView extends View { + private Font font; + private FontMetrics fontMetrics; + private Color fg, bg; + + public SegmentMarkView(Element elem) { + super(elem); + } + + /** + * Calculate alignment on the line. + */ + @Override + public float getAlignment(int axis) { + updateDrawSettings(); + switch (axis) { + case View.X_AXIS: + return super.getAlignment(axis); + case View.Y_AXIS: + float h = fontMetrics.getHeight(); + float d = fontMetrics.getDescent(); + return (h > 0) ? (h - d) / h : 0; + default: + throw new IllegalArgumentException("Invalid axis: " + axis); + } + } + + /** + * Calculate view size. + */ + @Override + public float getPreferredSpan(int axis) { + updateDrawSettings(); + switch (axis) { + case View.X_AXIS: + return fontMetrics.stringWidth(getText()); + case View.Y_AXIS: + return fontMetrics.getHeight(); + default: + throw new IllegalArgumentException("Invalid axis: " + axis); + } + } + + /** + * Calculate where position should be displayed. Used for display caret. + */ + @Override + public Shape modelToView(int pos, Shape a, Bias b) + throws BadLocationException { + Rectangle alloc = (a instanceof Rectangle) ? (Rectangle) a : a + .getBounds(); + + Rectangle lineArea = new Rectangle(); + + String text = getText(); + int p0 = getElement().getStartOffset(); + // fill in the results and return + lineArea.x = alloc.x + + fontMetrics.stringWidth(text.substring(0, pos - p0)); + lineArea.y = alloc.y; + lineArea.width = 0; + lineArea.height = fontMetrics.getHeight(); + return lineArea; + } + + /** + * Calculate what position should be displayed at point. Used for position + * caret after mouse click. + */ + @Override + public int viewToModel(float x, float y, Shape a, Bias[] biasReturn) { + String text = getText(); + int p0 = getElement().getStartOffset(); + + float prev = 0; + float beg = x - a.getBounds().x; + for (int i = 0; i <= text.length(); i++) { + float pos = fontMetrics.stringWidth(text.substring(0, i)) - beg; + if (pos > 0) { + return pos < -prev ? i + p0 : i - 1 + p0; + } + prev = pos; + } + return p0 + text.length(); + } + + /** + * Paint this view. + */ + @Override + public void paint(Graphics g, Shape a) { + updateDrawSettings(); + + Rectangle alloc = (a instanceof Rectangle) ? (Rectangle) a : a + .getBounds(); + + if (bg != null) { + g.setColor(bg); + g.fillRect(alloc.x, alloc.y, alloc.width, alloc.height); + } + + g.setFont(font); + g.setColor(fg); + String text = getText(); + + int y = alloc.getBounds().y + fontMetrics.getHeight() + - fontMetrics.getDescent(); + + g.drawChars(text.toCharArray(), 0, text.length(), alloc.getBounds().x, + y); + } + + /** + * Get view's text from document. + * + * @return text + */ + private String getText() { + int p0 = getElement().getStartOffset(); + int p1 = getElement().getEndOffset(); + try { + return getElement().getDocument().getText(p0, p1 - p0); + } catch (BadLocationException ex) { + throw new RuntimeException("Invalid location", ex); + } + } + + /** + * Update view draw settings. + */ + private void updateDrawSettings() { + if (font == null) { + AttributeSet attrs = getElement().getAttributes(); + StyledDocument doc = (StyledDocument) getDocument(); + font = doc.getFont(attrs); + fontMetrics = getContainer().getFontMetrics(font); + + fg = doc.getForeground(attrs); + if (attrs.isDefined(StyleConstants.Background)) { + bg = doc.getBackground(attrs); + } else { + bg = null; + } + } + } +} Property changes on: branches/prototypes/new-editor/src/org/omegat/gui/editor/SegmentMarkView.java ___________________________________________________________________ Added: svn:mime-type + text/x-java Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |