Changeset 1200 for trunk


Ignore:
Timestamp:
11/28/18 16:16:29 (6 years ago)
Author:
bln4
Message:

org.expeditee.auth.gio.EncryptedExpReader ->
org.expeditee.auth.gio.EncryptedExpWriter ->
org.expeditee.io.DefaultFrameReader ->
org.expeditee.io.DefaultFrameWriter ->
org.expeditee.io.ExpReader ->
org.expeditee.io.ExpWriter ->

The beginnings of a authentication system for Expeditee. Frame files (.exp) can now be encrypted with a password. A login system is being developed to accompany this.


org.expeditee.gui.AttributeUtils ->
org.expeditee.gui.Frame ->
org.expeditee.gui.FrameUtils ->
org.expeditee.items.Item ->
org.expeditee.items.PermissionPair ->
org.expeditee.items.Text ->

As part of the development the login screen. Modifications to Text Items have been made. New properties are 'Mask' and 'MinWidth'. Mask allows you to set a character to use as...a mask...for example, a password field using '*'. MinWidth allows you to specify a minimum width for text boxes. A text box with a minimum width never shrinks below this width; even when it has no content.

Location:
trunk/src/org/expeditee
Files:
4 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/expeditee/gui/AttributeUtils.java

    r1188 r1200  
    283283                        _Attrib.put("Width",                Item.class.getMethod("getWidthToSave"),
    284284                                                            Item.class.getMethod("setWidth", pIntO));
     285                        _Attrib.put("MinWidth",                         Item.class.getMethod("getMinWidthToSave"),
     286                                                                                                Item.class.getMethod("setMinWidth", pIntO));
    285287                        _Attrib.put("X",                    null,
    286288                                                            Item.class.getMethod("setX", pFloat));
     
    307309                        _Attrib.put("LetterSpacing",            Text.class.getMethod("getLetterSpacing"),
    308310                                                                                                Text.class.getMethod("setLetterSpacing", pFloat));
     311                        _Attrib.put("Mask",                             Text.class.getMethod("getMask"),
     312                                                                                                Text.class.getMethod("setMask", pIntO));
    309313                       
    310314                        // Aliases for attribute setting
     
    340344                        _Attrib.alias("j",                  "justification");
    341345                        _Attrib.alias("w",                  "width");
     346                        _Attrib.alias("mw",                             "minwidth");   
    342347                        _Attrib.alias("as",                 "autostamp");
    343                        
    344 
    345348                } catch (SecurityException e) {
    346349                        // TODO Auto-generated catch block
  • trunk/src/org/expeditee/gui/Frame.java

    r1193 r1200  
    126126        private Stack<History> _redo = new Stack<History>();
    127127
    128         // basically just a list of smaller objects?
    129         // maybe a hashtable (id -> item?)
    130         // Note: Needs to be able to be iterated through (for painting)
    131128        private List<Item> _body = new ArrayList<Item>();
     129        private List<Item> _bodyHiddenDueToPermissions = new ArrayList<Item>();
    132130
    133131        // for drawing purposes
     
    964962        }
    965963
    966         public void removeItem(Item item)
    967         {
     964        public void removeItem(Item item) {
    968965                removeItem(item, true);
    969966        }
     
    26072604                return _observers != null && _observers.size() > 0;
    26082605        }
     2606       
     2607        public List<Item> getBodyItemsWithInsufficientPermissions() {
     2608                return _bodyHiddenDueToPermissions;
     2609        }
     2610       
     2611        public void moveItemToBodyHiddenDueToPermission(final Item i) {
     2612                _body.remove(i);
     2613                _bodyHiddenDueToPermissions.add(i);
     2614        }
    26092615
    26102616        public Collection<? extends Item> getInteractableItems()
  • trunk/src/org/expeditee/gui/FrameIO.java

    r1188 r1200  
    4040import org.expeditee.actions.Actions;
    4141import org.expeditee.agents.ExistingFramesetException;
     42import org.expeditee.auth.io.EncryptedExpReader;
     43import org.expeditee.auth.io.EncryptedExpWriter;
    4244import org.expeditee.io.Conversion;
    4345import org.expeditee.io.ExpReader;
     
    465467
    466468                        if (fullPath.endsWith(ExpReader.EXTENTION)) {
    467                                 reader = new ExpReader(frameName);
     469                                if (EncryptedExpReader.isEncryptedExpediteeFile(fullPath)) {
     470                                        reader = new EncryptedExpReader(frameName);
     471                                } else {
     472                                        reader = new ExpReader(frameName);
     473                                }
    468474                        } else {
    469475                                reader = new KMSReader();
     
    952958                /* Dont save the frame if it has the noSave tag */
    953959                if (toSave.hasAnnotation("nosave")) {
    954                         Actions.PerformActionCatchErrors(toSave, null, "Restore");
     960                        Actions.LegacyPerformActionCatchErrors(toSave, null, "Restore");
    955961                        return "";
    956962                }
     
    964970                /* Format the frame if it has the autoFormat tag */
    965971                if (toSave.hasAnnotation("autoformat")) {
    966                         Actions.PerformActionCatchErrors(toSave, null, "Format");
     972                        Actions.LegacyPerformActionCatchErrors(toSave, null, "Format");
    967973                }
    968974
     
    988994                        // if its a new frame or an existing Exp frame...
    989995                        if (fullPath == null || fullPath.endsWith(ExpReader.EXTENTION)) {
    990                                 writer = new ExpWriter();
     996                                //writer = new ExpWriter();
     997                                writer = new ExpWriter();//new EncryptedExpWriter();
    991998                                savedVersion = ExpReader.getVersion(fullPath);
    992999                        } else {
     
    11981205        public static Frame LoadProfile(String userName)
    11991206        {
    1200                 return LoadFrame(userName + "1");
     1207                final String profilesLoc = System.getProperty("profiles.loc");
     1208                if (profilesLoc != null) {
     1209                        return LoadFrame(userName + "1", profilesLoc);
     1210                } else {
     1211                        return LoadFrame(userName + "1");
     1212                }
    12011213        }
    12021214
  • trunk/src/org/expeditee/gui/FrameUtils.java

    r1193 r1200  
    12881288                                                }
    12891289                                        }
     1290                                       
     1291                                        if (i.getData() != null && !i.getData().isEmpty() && i.getText().isEmpty()) {
     1292                                                System.err.println();
     1293                                        }
    12901294
    12911295                                        if (i.contains(new Point(x, y))){
     
    18671871                                }
    18681872                        }
    1869                         if (lastEdited != LastEdited && LastEdited.getText().length() == 0) {
     1873                        if (lastEdited != LastEdited && LastEdited.getText().length() == 0 && LastEdited.getMinWidth() == null) {
    18701874                                parent.removeItem(LastEdited);
    18711875                        }
  • trunk/src/org/expeditee/io/DefaultFrameReader.java

    r1102 r1200  
    9696                                        pColor));
    9797
     98                        // Note: As of 26/11/18 there are no unused letter item tags.  Use other characters.
    9899                        _ItemTags.put('S', Item.class.getMethod("setID", pInt));
    99100                        _ItemTags.put('s', Item.class.getMethod("setDateCreated", pString));
     
    150151                        _ItemTags.put('m', Text.class.getMethod("setInitialSpacing", pFloat));
    151152                        _ItemTags.put('w', Text.class.getMethod("setWidth", pIntO));
     153                        _ItemTags.put('M', Text.class.getMethod("setMinWidth", pIntO));
    152154                        _ItemTags.put('k', Text.class.getMethod("setJustification", pJustification));
    153155                        _ItemTags.put('r', Text.class.getMethod("setAutoWrap", pBool));
     
    161163                       
    162164                        _ItemTags.put('p', Item.class.getMethod("setPermission", pPermission));
     165                       
     166                        _ItemTags.put('O', Text.class.getMethod("setMask", pIntO));
    163167                       
    164168                        // Lines and constraints are created differently
  • trunk/src/org/expeditee/io/DefaultFrameWriter.java

    r1102 r1200  
    3333import org.expeditee.agents.WriteTree;
    3434import org.expeditee.gio.EcosystemManager;
    35 import org.expeditee.gui.Browser;
    3635import org.expeditee.gui.Frame;
    3736import org.expeditee.gui.FrameIO;
     
    8079                        _FrameTags.put('B', Frame.class.getMethod("getBackgroundColor"));
    8180                       
     81                        // Note: As of 26/11/18 there are no unused letter item tags.  Use other characters.
    8282                        _ItemTags.put('S', Item.class.getMethod("getTypeAndID"));
    8383                        _ItemTags.put('s', Item.class.getMethod("getDateCreated"));
     
    120120                        _ItemTags.put('f', Text.class.getMethod("getFont"));
    121121                        _ItemTags.put('t', Text.class.getMethod("getSpacing"));
     122                       
     123                        _ItemTags.put('O', Text.class.getMethod("getMask"));
    122124
    123125                        // TODO set a boolean flag to indicate that the text is a formula
     
    129131                        _ItemTags.put('m', Text.class.getMethod("getInitialSpacing"));
    130132                        _ItemTags.put('w', Text.class.getMethod("getWidthToSave"));
     133                        _ItemTags.put('M', Text.class.getMethod("getMinWidthToSave"));
    131134                        _ItemTags.put('k', Text.class.getMethod("getJustification"));
    132135                        _ItemTags.put('r', Text.class.getMethod("getAutoWrapToSave"));
  • trunk/src/org/expeditee/io/ExpReader.java

    r1189 r1200  
    6868         */
    6969        protected static boolean isValidLine(String s) {
    70                 return s.length() >= 2 && s.charAt(1) == ' '
    71                                 && (Character.isLetter(s.charAt(0)) || s.charAt(0) == '[' || s.charAt(0) == ']' || s.charAt(0) == '^' || s.charAt(0) == '_');
     70                // Previously lines in a .exp file had to start with a letter (A-Z, a-z).  This allowed for an efficient check for valid lines.
     71                // As we started to run out of spare letters to use for properties, we wished to use the full range of characters.  But we did not
     72                // wish to loose the efficiency of the Character.isLetter check.  In order to maintain as much of this efficiency as possible, but
     73                // allow for all characters, we take advantage of how || is evaluated:
     74                //              if the check for Character.isLetter passes, then the more complex map lookup operation does not take place.
     75                return s.length() >= 2 && (Character.isLetter(s.charAt(0)) || _ItemTags.keySet().contains(s.charAt(0)));
    7276        }
    7377
     
    117121                                                        break;
    118122                                                }
    119                                                 _linePoints.put(currentItem.getID(), currentItem);
     123                                                _linePoints.put(currentItem.getID(), currentItem);                                             
    120124                                                newFrame.addItem(currentItem);
    121125                                        } else if (currentItem != null && actionShouldBeDelayed(getTag(next))) {
     
    123127                                        } else if (currentItem != null) {
    124128                                                processBodyLine(currentItem, next);
     129//                                              final boolean hasSpecifiedPermission = currentItem.getPermission() != null;
     130//                                              final boolean hasSpecifiedOwner = currentItem.getOwner() != null;
     131//                                              if (hasSpecifiedPermission && hasSpecifiedOwner && currentItem.getPermission().getPermission(currentItem.getOwner()) == UserAppliedPermission.denied) {
     132//                                                      newFrame.removeItem(currentItem);
     133//                                                      newFrame.addItemHidden(currentItem);
     134//                                                      continue;
     135//                                              }
    125136                                        } else {
    126137                                                System.err.println("Error while reading in frame (ExpReader): Found body line but no current item to apply it to.");
     
    236247                Character tag = getTag(line);
    237248                String value = getValue(line);
    238 
     249               
    239250                Method toRun = _ItemTags.get(tag);
     251                               
    240252                if (toRun == null) {
    241253                        System.out.println("Error accessing tag method: " + tag);
    242254                }
     255                               
    243256                Object[] vals = Conversion.Convert(toRun, value);
    244 
    245257                try {
    246258                        if (vals != null) {
     
    322334                                        String value = getValue(next);
    323335                                        if (tag.equals('V')) {
     336                                                reader.close();
    324337                                                return Integer.parseInt(value);
    325338                                        }
    326339                                }
    327340                        }
     341                        reader.close();
    328342                } catch (Exception e) {
    329343                }
  • trunk/src/org/expeditee/io/ExpWriter.java

    r919 r1200  
    4747public class ExpWriter extends DefaultFrameWriter {
    4848
    49         private ProxyWriter _writer = null;
     49        protected ProxyWriter _writer = null;
    5050
    5151        protected StringBuilder _stringWriter = null;
     
    104104                if (_writer == null)
    105105                        return;
     106               
     107                preOutputFrame();
    106108
    107109                writeHeader(frame);
     
    109111                // write each item in the frame
    110112                for (Item i : frame.getItemsToSave()) {
     113                        assert (!(i instanceof Line));
     114                        writeItem(i);
     115                }
     116               
     117                for (final Item i: frame.getBodyItemsWithInsufficientPermissions()) {
    111118                        assert (!(i instanceof Line));
    112119                        writeItem(i);
     
    122129
    123130                return;
     131        }
     132
     133        protected void preOutputFrame() {
    124134        }
    125135
  • trunk/src/org/expeditee/items/Item.java

    r1190 r1200  
    5050import org.expeditee.gui.DisplayController;
    5151import org.expeditee.gui.Frame;
    52 import org.expeditee.gui.FrameGraphics;
    5352import org.expeditee.gui.FrameIO;
    5453import org.expeditee.gui.FrameUtils;
     
    5958import org.expeditee.io.Conversion;
    6059import org.expeditee.settings.UserSettings;
     60import org.expeditee.settings.legacy.LegacyFeatures;
    6161import org.expeditee.simple.Context;
    6262import org.expeditee.stats.AgentStats;
     
    275275
    276276        private List<String> _data = null;
    277 
     277         
    278278        private String _formula = null;
    279279
     
    309309
    310310        protected boolean _filled = true;
     311       
     312        // NGIKM Attributes
     313        private List<String> _ngikmLabels = new ArrayList<String>();
     314        private List<String> _ngikmKeys = new ArrayList<String>();
    311315
    312316        /** Just calls source.duplicateOnto(dest). */
     
    380384
    381385                dest._visible = this._visible;
     386               
     387                dest._ngikmKeys = new ArrayList<String>(this._ngikmKeys);
     388                dest._ngikmLabels = new ArrayList<String>(this._ngikmLabels);
    382389
    383390                Frame parent = DisplayController.getCurrentFrame();
     
    494501        {
    495502                _permissionPair = permissionPair;
     503                if (_permissionPair.getPermission(_owner) == UserAppliedPermission.denied) {
     504                        this.getParent().moveItemToBodyHiddenDueToPermission(this);
     505                }
    496506        }
    497507       
     
    11551165                return getWidth();
    11561166        }
     1167       
     1168        public Integer getMinWidthToSave() {
     1169                return getMinWidth();
     1170        }
    11571171
    11581172        public Integer getWidth()
    11591173        {
     1174                return null;
     1175        }
     1176       
     1177        public Integer getMinWidth() {
    11601178                return null;
    11611179        }
     
    14581476
    14591477                for (String s : getAction()) {
    1460                         Object returnValue = Actions.PerformActionCatchErrors(sourceFrame,
    1461                                         sourceItem, s);
     1478                        Object returnValue;
     1479                        if (LegacyFeatures.UseLegacyActionArgumentMapping.get()) {
     1480                                returnValue = Actions.LegacyPerformActionCatchErrors(sourceFrame, sourceItem, s);
     1481                        } else {
     1482                                returnValue = Actions.PerformActionCatchErrors(sourceFrame, sourceItem, s, this);
     1483                        }
     1484                       
    14621485                        if (returnValue != null) {
    14631486                                FreeItems.getInstance().clear();
     
    22542277                throw new UnsupportedOperationException("Item type does not support width attribute!");
    22552278        }
     2279       
     2280        public void setMinWidth(final Integer width) throws UnsupportedOperationException {
     2281                throw new UnsupportedOperationException("Item type does not support minwidth attribute.");
     2282        }
    22562283
    22572284        public void setRightMargin(int i, boolean fixWidth)
     
    22832310         */
    22842311        public void setY(float newY) {
     2312                if (newY == 265) {
     2313                        System.err.println("Item::setY::setting y to 265");
     2314                }
    22852315                setPosition(getX(), newY);
    22862316        }
  • trunk/src/org/expeditee/items/PermissionPair.java

    r1193 r1200  
    3535                        if (permissionCode.length() != 0) {
    3636
    37                                 if (permissionCode.length() == 1) {
     37                                if (permissionCode.length() == 1 || (permissionCode.length() == 2 && permissionCode.startsWith("-"))) {
    3838                                        // replicate it to cover ifOwner/ifNotOwner
    3939                                        permissionCode += permissionCode;
     
    5050                                ownerPermission = UserAppliedPermission.getPermission(ownerPermissionCode, defaultPermission);
    5151                                notOwnerPermission = UserAppliedPermission.getPermission(notOwnerPermissionCode, defaultPermission);
    52                                 //ownerPermission = UserAppliedPermission.getPermission(permissionCode.substring(0, 1),
    53                                 //              defaultPermission);
    54                                 //notOwnerPermission = UserAppliedPermission.getPermission(permissionCode.substring(1, 2),
    55                                 //              defaultPermission);
    5652                        }
    5753                }
  • trunk/src/org/expeditee/items/Text.java

    r1190 r1200  
    136136         */
    137137        private Integer _maxWidth = -Integer.MAX_VALUE;
     138       
     139        private Integer _minWidth = -Integer.MAX_VALUE;
    138140
    139141        private Justification _justification = Justification.left;
     
    172174
    173175        // text is broken up into lines
    174         private StringBuffer _text = new StringBuffer();
    175 
    176         private List<TextLayout> _textLayouts = new LinkedList<TextLayout>();
     176        protected StringBuffer _text = new StringBuffer();
     177
     178        protected List<TextLayout> _textLayouts = new LinkedList<TextLayout>();
    177179
    178180        // The font to display this text in
    179181        private Font _font;
     182       
     183        // The optional mask character to us in place of the text's content.
     184        private Integer _mask = null;
    180185
    181186        protected static void InitFontFamily(File fontFamilyDir)
     
    373378
    374379        /**
    375 <<<<<<< .mine
    376          * Sets the maximum width of this Text item when justification is used.
    377          * passing in 0 or -1 means there is no maximum width
    378 ||||||| .r1094
    379          * Sets the maximum width of this Text item when justifcation is used.
    380          * passing in 0 or -1 means there is no maximum width
    381 =======
    382          * Sets the maximum width of this Text item when justifcation is used. passing
    383          * in 0 or -1 means there is no maximum width
    384 >>>>>>> .r1100
    385          *
    386380         * @param width
    387381         *            The maximum width of this item when justification is applied to
     
    399393
    400394                _maxWidth = width;
     395                rebuild(true);
     396                invalidateAll();
     397        }
     398       
     399        @Override
     400        public void setMinWidth(final Integer width) {
     401                invalidateAll();
     402               
     403                if (width == null) {
     404                        setJustification(Justification.left);
     405                        setRightMargin(DisplayController.getFramePaintArea().getWidth(), false);
     406                        return;
     407                }
     408               
     409                _minWidth = width;
    401410                rebuild(true);
    402411                invalidateAll();
     
    433442
    434443                return Math.abs(_maxWidth);
     444        }
     445       
     446        public Integer getMinWidth() {
     447                if (_minWidth == null || _minWidth <= 0) {
     448                        return null;
     449                }
     450                return _minWidth;
     451        }
     452       
     453        public Integer getAbsoluteMinWidth() {
     454                if (_minWidth == null) {
     455                        return Integer.MAX_VALUE;
     456                }
     457                return Math.abs(_minWidth);
    435458        }
    436459
     
    10351058                        lineIndex = newLine;
    10361059                }
    1037 
    1038                 // move the cursor to the new location
    1039                 float[] caret = current.getCaretInfo(hit);
    1040                 float y = getLineDrop(current) * lineIndex;
    1041                 y = getY() + y + caret[1];
    1042 
    1043                 float x = getX() + caret[0] + getJustOffset(current);
    1044                 x = Math.min(x, (getX() - Item.MARGIN_RIGHT - (2 * getGravity()) + getBoundsWidth()));
    1045 
    1046                 invalidateAll();
    10471060               
    1048 //              System.err.println("Mouse location: " + mouseX + "," + mouseY);
    1049 //              System.err.println("Caret location: " + caret[0] + "," + caret[1]);
    1050 
    1051 //              System.err.println(text);
    1052 //              System.err.println("X delta: " + (x - getX()));
    1053                 final Point newCursor = new Point(Math.round(x), Math.round(y));
    1054 //              System.err.println("Moving cursor to: " + newCursor);
    1055                 return newCursor;
     1061                if (this.getMask() != null) {
     1062                        // If we are working with a mask than the positioning of the mouse is simplified. (as character length is constant)
     1063                        String content = "";
     1064                        for (int i = 0; i < this._text.length(); i++) {
     1065                                content += (char) this.getMask().intValue();
     1066                        }
     1067                        final TextLayout fakeLayout = TextLayout.getManager().layoutStringSimple(content, this.getFont());
     1068                        //final TextHitInfo fakeHitInfo = fakeLayout.getNextRightHit(hit.getCharIndex());
     1069                        final float[] fakeCaretInfo = fakeLayout.getCaretInfo(hit);
     1070                       
     1071                        float y = getLineDrop(current) * lineIndex;
     1072                        y = getY() + y + fakeCaretInfo[1];
     1073                        float x = getX() + fakeCaretInfo[0] + getJustOffset(current);
     1074                        x = Math.min(x, (getX() - Item.MARGIN_RIGHT - (2 * getGravity()) + getBoundsWidth()));
     1075                       
     1076                        return new Point(Math.round(x), Math.round(y));
     1077                } else {
     1078                        // If we have no mask then....
     1079                        // move the cursor to the new location
     1080                        float[] caret = current.getCaretInfo(hit);
     1081                        float y = getLineDrop(current) * lineIndex;
     1082                        y = getY() + y + caret[1];
     1083
     1084                        float x = getX() + caret[0] + getJustOffset(current);
     1085                        x = Math.min(x, (getX() - Item.MARGIN_RIGHT - (2 * getGravity()) + getBoundsWidth()));
     1086
     1087                        invalidateAll();
     1088                       
     1089                        final Point newCursor = new Point(Math.round(x), Math.round(y));
     1090                        return newCursor;
     1091                }
    10561092        }
    10571093
     
    15031539         *              The distance to advance in the y-direction before the next line.
    15041540         */
    1505         private float getLineDrop(TextLayout layout)
     1541        protected float getLineDrop(TextLayout layout)
    15061542        {
    15071543                if (getSpacing() < 0) {
     
    16201656                        return false;
    16211657                }
     1658               
     1659                if (this.getMinWidth() != null && outline.contains(mouseX,  mouseY)) {
     1660                        return true;
     1661                }
    16221662
    16231663                for (TextLayout text : _textLayouts) {
     
    16281668                        // gravity of right
    16291669                        int justOffset = getJustOffset(text);
    1630 
     1670                       
    16311671                        if (mouseY - textY > textOutline.getMinY() &&
    16321672                                        mouseY - textY < textOutline.getMinY() + textOutline.getHeight() &&
     
    16531693                }
    16541694
    1655                 if (_textLayouts == null || _textLayouts.size() < 1) {
     1695                // if there is no text layouts and the text has no min width, do nothing
     1696                if (_textLayouts == null || (_textLayouts.size() < 1 && this.getMinWidth() == null)) {
    16561697                        return null;
    1657                 }
     1698                } 
    16581699
    16591700                int preChangeWidth = 0;
     
    16691710
    16701711                float y = -1;
     1712               
     1713                if (this.getMinWidth() != null && _textLayouts.size() == 0 && this.getFont() != null) {
     1714                        final TextLayout fakeLayout = TextLayout.getManager().layoutStringSimple("p", this.getFont());
     1715                        final int xPos = getX() - getGravity();
     1716                        final int yPos = getY() - getGravity() - (int) fakeLayout.getAscent();
     1717                        final int width = 2 * getGravity() + this.getMinWidth();
     1718                        final int height = 2 * getGravity() + EcosystemManager.getGraphicsManager().getFontHeight(getFont());
     1719                        TextLayout.getManager().releaseLayout(fakeLayout);
     1720                        return new AxisAlignedBoxBounds(xPos, yPos, width, height);
     1721                }
    16711722
    16721723                // Fix concurrency error in ScaleFrameset
     
    16761727                }
    16771728
    1678                 for (TextLayout layout : tmpTextLayouts) {
     1729                for (int index = 0; index < tmpTextLayouts.size(); index++) {
     1730                        final TextLayout layout = tmpTextLayouts.get(index);
    16791731                        AxisAlignedBoxBounds bounds = layout.getLogicalHighlightShape(0, layout.getCharacterCount());
    16801732
    16811733                        if (y < 0) {
    16821734                                y = 0;
    1683                         } else {
     1735                        } else { 
    16841736                                y += getLineDrop(layout);
    16851737                        }
    1686 
    1687                         maxX = Math.max(maxX, bounds.getMaxX());
     1738                       
     1739                        int minWidth = getAbsoluteMinWidth();
     1740
    16881741                        minX = Math.min(minX, bounds.getMinX());
     1742                        maxX = minWidth < Integer.MAX_VALUE
     1743                                        ? Math.max(minX + minWidth, bounds.getMaxX())
     1744                                        : Math.max(maxX, bounds.getMaxX());
     1745                        minY = Math.min(minY, (int) (bounds.getMinY() + y));
    16891746                        maxY = Math.max(maxY, (int) (bounds.getMaxY() + y));
    1690                         minY = Math.min(minY, (int) (bounds.getMinY() + y));
    16911747                }
    16921748
     
    18051861                        //System.err.println(Arrays.toString(_text.toString().toCharArray()));
    18061862                }
     1863               
    18071864                invalidateBounds();
    1808 
    18091865        }
    18101866
     
    19331989
    19341990                // if there is no text to paint, do nothing.
    1935                 if (_text == null || _text.length() == 0) {
     1991                if (_text == null) {
     1992                        return;
     1993                }
     1994               
     1995                // if the text to paint is empty string and there is no min width, do nothing.
     1996                if ((_text.length() == 0 && getMinWidth() == null)) {
    19361997                        return;
    19371998                }
     
    20012062                                fill = null;
    20022063                        }
    2003 //                      System.err.println("Top left: " + getBoundingBox().getTopLeft() + ", " + "Bottom right: " + getBoundingBox().getBottomRight());
    20042064                        g.drawRectangle(bounds, 0.0, fill, getPaintHighlightColor(), highlightStroke, null);
    20052065                }
     
    20322092                                }
    20332093
     2094                                if (layout.getCharacterCount() == 0) { continue; }
    20342095                                int ldx = 1 + getX() + getJustOffset(layout); // Layout draw x
    2035 
    2036                                 g.drawTextLayout(layout, new Point(ldx, (int) y), paintColour);
     2096                                if (_mask == null) {
     2097                                        g.drawTextLayout(layout, new Point(ldx, (int) y), paintColour);
     2098                                } else {
     2099                                        String mask = "";
     2100                                        for(int o = 0; o < layout.getCharacterCount(); o++) { mask += (char) getMask().intValue(); }
     2101                                        g.drawString(mask, new Point(ldx, (int) y), layout.getFont(), paintColour);
     2102                                }
    20372103
    20382104                                y += getLineDrop(layout);
    20392105                        }
    20402106                }
    2041 
     2107               
    20422108                paintLink();
    20432109        }
     
    20762142                copy.setWidth(getWidthToSave());
    20772143                copy.setFont(getFont().clone());
     2144                copy.setMinWidth(getMinWidthToSave());
     2145                copy.setMask(_mask);
    20782146                if (hasFormula()) {
    20792147                        copy.calculate(getFormula());
     
    21682236
    21692237                if (_text.length() == 0) {
     2238                        if (this.getMinWidth() != null) {
     2239//                              final TextLayout base = _textLayouts.get(0);
     2240//                              _textLayouts.set(0, TextLayout.get(" ", base.getFont(), 0, 1));
     2241                                _textLayouts.clear();
     2242                        }
    21702243                        if (this.isLineEnd()) {
    21712244                                // Remove and replace with a dot
     
    24962569                String text = getText();
    24972570                assert (text != null);
    2498                 return text.trim().length() == 0 || super.dontSave();
     2571                return super.dontSave() || (text.trim().length() == 0 && this.getMinWidth() == null);
    24992572        }
    25002573
     
    27132786        @Override
    27142787        public void setAnchorTop(Integer anchor) {
    2715                 if (!isLineEnd()) {
     2788                if (!isLineEnd()) {                     
    27162789                        super.setAnchorTop(anchor);
    27172790                        if (anchor != null) {
    2718                                 setY(anchor + _textLayouts.get(0).getAscent());
     2791                                if (!_textLayouts.isEmpty()) {
     2792                                        final float ascent = _textLayouts.get(0).getAscent();
     2793                                        setY(anchor + ascent);
     2794                                } else if (this.getFont() != null) {           
     2795                                        // p could be any character
     2796                                        final TextLayout fakeLayout = TextLayout.getManager().layoutStringSimple("p", this.getFont());
     2797                                        final float ascent = fakeLayout.getAscent();
     2798                                        EcosystemManager.getTextLayoutManager().releaseLayout(fakeLayout);
     2799                                        setY(anchor + ascent);
     2800                                }
    27192801                        }
    27202802                        return;
     
    27402822                        super.setAnchorBottom(anchor);
    27412823                        if (anchor != null) {
    2742                                 setY(DisplayController.getFramePaintArea().getHeight() - (anchor + this.getBoundsHeight() - _textLayouts.get(0).getAscent() - _textLayouts.get(0).getDescent()));
     2824                                if (!_textLayouts.isEmpty()) {
     2825                                        final float ascent = _textLayouts.get(0).getAscent();
     2826                                        final float descent = _textLayouts.get(0).getDescent();
     2827                                        setY(DisplayController.getFramePaintArea().getHeight() - (anchor + this.getBoundsHeight() - ascent - descent));
     2828                                } else if (this.getFont() != null) {
     2829                                        // p could be any character
     2830                                        final TextLayout fakeLayout = TextLayout.getManager().layoutStringSimple("p", this.getFont());
     2831                                        final float ascent = fakeLayout.getAscent();
     2832                                        final float descent = fakeLayout.getDescent();
     2833                                        setY(DisplayController.getFramePaintArea().getHeight() - (anchor + this.getBoundsHeight() - ascent - descent));
     2834                                }
     2835                               
    27432836                        }
    27442837                        return;
     
    30553148                        DisplayController.setCursorPosition(newText.getParagraphEndPosition());
    30563149                }
    3057 
    3058         }
     3150        }
     3151       
     3152        public Integer getMask() {
     3153                if (_mask == null) { return null; }
     3154                else { return _mask; }
     3155        }
     3156       
     3157        public void setMask(final Integer c) { _mask = c; }
    30593158}
Note: See TracChangeset for help on using the changeset viewer.