package org.expeditee.gui; import java.awt.Color; import java.awt.Dimension; import java.awt.Image; import java.awt.Polygon; import java.awt.image.ImageObserver; import java.awt.image.VolatileImage; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Stack; import org.expeditee.io.Conversion; import org.expeditee.io.Logger; import org.expeditee.items.Dot; import org.expeditee.items.Item; import org.expeditee.items.ItemUtils; import org.expeditee.items.Line; import org.expeditee.items.Text; /** * Represents a KMS Frame that is displayed on the screen. Also is a registered * MouseListener on the Browser, and processes any MouseEvents directly. * * @author jdm18 * */ public class Frame implements ImageObserver { public static final Color[] COLOR_WHEEL = { Color.BLACK, Color.GRAY, new Color(235, 235, 235), new Color(225, 225, 255), new Color(195, 255, 255), new Color(225, 255, 225), new Color(255, 255, 195), new Color(255, 225, 225), new Color(255, 195, 255), null }; // The various attributes of this Frame /** * TODO: Change these to non-string attributes (where applicable). All * processing to\from Java types should be done in KMSReader and KMSWriter. */ private String _frameset = null; private int _number = -1; private int _version = 1; private int _fversion = -1; private String _protection = null; private String _owner = null; private String _creationDate = null; private String _modifiedUser = null; private String _modifiedDate = null; private String _frozenDate = null; private Color _background; private Color _foreground; public String path; private boolean _sorted = true; // The items contained in this Frame // records whether a change has been made to this Frame (for saving // purposes). private boolean _change = false; private boolean _saved = false; // list of deleted items that can be restored private Stack _undo = new Stack(); // basically just a list of smaller objects? // maybe a hashtable (id -> item?) // Note: Needs to be able to be iterated through (for painting) private List _body = new ArrayList(); public static List FreeItems = new ArrayList(); private int _lineCount = 0; private int _itemCount = 1; // The frameName to display on the screen private Text _frameName = null; // private Text _template = UserSettings.ItemTemplate.copy(); private List _overlays = new ArrayList(); private VolatileImage _buffer = null; private boolean _validBuffer = true; /** * Default constructor, nothing is set. */ public Frame() { // _template.setParent(this); } public VolatileImage getBuffer() { return _buffer; } public void setBuffer(VolatileImage newBuffer) { _buffer = newBuffer; // setBufferValid(true); } public boolean isBufferValid() { if (_buffer != null && _buffer.contentsLost()) return false; return _validBuffer; } public void setBufferValid(boolean newValue) { _validBuffer = newValue; } public int getNextItemID() { return ++_itemCount; } public void updateIDs(List items) { for (Item i : items) if (!(i instanceof Line)) i.setID(getNextItemID()); else i.setID(++_lineCount); } /** * Returns whether this Frame has been changed and required saving to disk. * * @return True if this Frame has been altered, false otherwise. */ public boolean hasChanged() { // virtual frames are never saved if (_number == -1) return false; return _change; } /** * Sets whether this Frame should be saved to disk. * * @param value * False if this Frame should be saved to disk, False otherwise. */ public void setChanged(boolean value) { _change = value; if (_change) setBufferValid(false); } // indicates the frame has changed private void change() { setChanged(true); } /** * Returns an ArrayList of all Items currently on the Frame (excludes Items * attached to the cursor). * * @return The list of Item objects that are on this Frame. */ public List getItems() { if (!_sorted) { Collections.sort(_body); _sorted = true; } return _body; } /** * Returns a list of all the non annotation text items on the frame which * are not the title or frame name. * * @return the list of body text items. */ public List getBodyTextItems() { List bodyTextItems = new ArrayList(); Text frameTitle = getTitle(); for (Item i : getItems()) { // only add up normal body text items if (i instanceof Text && i != _frameName && i != frameTitle && !i.isAnnotation()) { bodyTextItems.add((Text) i); } } return bodyTextItems; } /** * Gets the last item on the frame that is a non annotation item but is also * text. * * @return the last non annotation text item. */ public Text getLastNonAnnotationTextItem() { List items = getItems(); // find the last non-annotation text item for (int i = (items.size() - 1); i >= 0; i--) { Item it = items.get(i); if (it instanceof Text && !it.isAnnotation()) { return (Text) it; } } return null; } /** * Iterates through the list of items on the frame, and returns one with the * given id if one exists, otherwise returns null. * * @param id * The id to search for in the list of items * @return The item on this frame with the given ID, or null if one is not * found. */ public Item getItemWithID(int id) { for (Item i : _body) if (i.getID() == id) return i; return null; } /** * Sets this Frame's Title which is displayed in the top left corner. * * @param title * The title to assign to this Frame */ public void setTitle(String title) { if (title == null || title == "") return; boolean oldchange = _change; // remove any numbering this title has title = title.replaceAll("^\\d*[.] *", ""); Text frameTitle = getTitle(); if (frameTitle == null) { if (UserSettings.TitleTemplate == null) { frameTitle = new Text(getNextItemID(), title); frameTitle.setPosition(Item.MARGIN_LEFT + org.expeditee.io.Conversion.X_ADJUST, org.expeditee.io.Conversion.Y_ADJUST); } else { frameTitle = UserSettings.TitleTemplate.copy(); frameTitle.setID(this.getNextItemID()); frameTitle.setText(title); } addItem(frameTitle); } else { frameTitle.setText(title); title = ItemUtils.StripTagSymbol(title); String autoBulletText = FrameKeyboardActions.getAutoBullet(title); if (autoBulletText.length() > 0) frameTitle.stripFirstWord(); } FrameUtils.Parse(this); // do not save if this is the only change setChanged(oldchange); } public Text getTitle() { List items = getItems(); for (Item i : items) { if (i instanceof Text /* && !i.isAnnotation() */&& i != _frameName) return (Text) i; } return null; } public Text getName() { return _frameName; } public Text getItemTemplate() { Text t = UserSettings.ItemTemplate; // check for an updated template... for (Item i : this.getItems()) { if (ItemUtils.isTag(i, ItemUtils.TAG_ITEM_TEMPLATE)) { t = (Text) i; break; } } // If the item is linked apply any attribute pairs on the child frame String link = t.getAbsoluteLink(); // need to get link first because copy doesnt copy the link t = t.copy(); if (link != null) { t.setLink(null); Frame childFrame = FrameIO.LoadFrame(link); if (childFrame != null) { // read in attribute value pairs for (Text attribute : childFrame.getBodyTextItems()) { AttributeUtils.SetAttribute(t, attribute); } } } return t; } public Text getAnnotationTemplate() { Text t = null; // check for an updated template... for (Item i : this.getItems()) { if (ItemUtils.isTag(i, ItemUtils.TAG_ANNOTATION_TEMPLATE)) { t = (Text) i; break; } } if (t == null) { if (UserSettings.AnnotationTemplate != null) t = UserSettings.AnnotationTemplate; else t = getItemTemplate(); } return t.copy(); } public Text getCodeCommentTemplate() { Text t = null; // check for an updated template... for (Item i : this.getItems()) { if (ItemUtils.isTag(i, ItemUtils.TAG_CODE_COMMENT_TEMPLATE)) { t = (Text) i; break; } } if (t == null) { if (UserSettings.CodeCommentTemplate != null) t = UserSettings.CodeCommentTemplate; else t = getItemTemplate(); } return t.copy(); } /* * public void setItemTemplate(Text template) { if (template != null) * _template = template; else _template = UserSettings.ItemTemplate.copy(); } */ /** * Returns any items on this frame that are within the given Shape. Also * returns any Items on overlay frames that are within the Shape. * * @param shape * The Shape to search for Items in * @return All Items on this Frame or overlayed Frames for which * Item.intersects(shape) return true. */ public List getItemsWithin(Polygon poly) { ArrayList results = new ArrayList(); for (Item i : _body) if (i.intersects(poly)) {// || shape.contains(i.getX(), // i.getY())){ if (!results.contains(i)) results.add(i); /* * List connected = i.getConnected(); for(Item item : * connected) if(!results.contains(item)) * results.add(item);//All(i.getConnected()); */ } for (Overlay o : _overlays) results.addAll(o.Frame.getItemsWithin(poly)); /* * ArrayList toInclude = new ArrayList(0); //remove lines * that do not have a point anchored in the polygon for(Item i : * results){ if(i instanceof Line){ Line line = (Line) i; * if(!(results.contains(line.getStartDot())) && * !(results.contains(line.getEndDot()))) removeLines.add(line); } } * * results.removeAll(removeLines); */ return results; } /** * Sets the name of this Frame to the given String, to be displayed in the * upper right corner. * * @param name * The name to use for this Frame. */ public void setFrameset(String name) { _frameset = name; } /** * Adjusts frameset names so that a period is appended if they end in a * digit. * * @param name * the unadjusted frame set name * @return the adjusted frame set name */ public String getFramesetNameAdjusted() { return _frameset + (Character.isDigit(_frameset.charAt(_frameset.length() - 1)) ? "." : ""); } /** * Adjusts a frameset name so a period is appended if it ends in a digit. * This form of the frameset name is used when referencing frames in the * frame set. * * @param frameset * @return */ public static String GetFramesetNameAdjusted(String frameset) { return frameset + (Character.isDigit(frameset.charAt(frameset.length() - 1)) ? "." : ""); } public void setFrameName(String framename) { int num = Conversion.getFrameNumber(framename); String frameset = Conversion.getFrameset(framename, false); setFrameset(frameset); setFrameNumber(num); } /** * Sets the frame number of this Frame to the given integer * * @param number * The number to set as the frame number */ public void setFrameNumber(int number) { _number = number; boolean oldchange = _change; int id; if (_frameName != null) { removeItem(_frameName); id = _frameName.getID(); } else id = -1 * getNextItemID(); _frameName = new Text(id); _frameName.setText(getFramesetNameAdjusted() + _number); _frameName.setPosition(FrameGraphics.getMaxFrameSize().width - _frameName.getBoundsWidth() - Item.MARGIN_RIGHT - org.expeditee.io.Conversion.X_ADJUST, org.expeditee.io.Conversion.Y_ADJUST); addItem(_frameName); setChanged(oldchange); } /** * Returns the number of this Frame. * * @return The Frame number of this Frame or -1 if it is not set. */ public int getFrameNumber() { return _number; } /** * Sets the version of this Frame to the given String. * * @param version * The version to use for this Frame. */ public void setVersion(int version) { _version = version; } /** * Sets the format version of this Frame to the given String. * * @param version * The format version to use for this Frame. */ public void setFormatVersion(int version) { _fversion = version; } /** * Sets the protection of this Frame to the given String. * * @param protection * The protection to use for this Frame. */ public void setProtection(String protection) { _protection = protection; } /** * Sets the owner of this Frame to the given String. * * @param owner * The owner to use for this Frame. */ public void setOwner(String owner) { _owner = owner; } /** * Sets the created date of this Frame to the given String. * * @param date * The date to use for this Frame. */ public void setDateCreated(String date) { _creationDate = date; _modifiedDate = date; for (Item i : _body) { i.setDateCreated(date); } } public void resetDateCreated() { setDateCreated(Logger.EasyDateFormat("ddMMMyyyy:HHmm")); } /** * Sets the last modifying user of this Frame to the given String. * * @param user * The user to set as the last modifying user. */ public void setLastModifyUser(String user) { _modifiedUser = user; } /** * Sets the last modified date of this Frame to the given String. * * @param date * The date to set as the last modified date. */ public void setLastModifyDate(String date) { _modifiedDate = date; } /** * Sets the last frozen date of this Frame to the given String. * * @param date * The date to set as the last frozen date. */ public void setFrozenDate(String date) { _frozenDate = date; } public void setResort(boolean value) { _sorted = !value; } /** * Adds the given Item to the body of this Frame. * * @param item * The Item to add to this Frame. */ public void addItem(Item item) { if (item != null) { if (_body.contains(item)) { System.out.println("Item (" + item.getClass().getSimpleName() + ") with ID " + item.getID() + " already in body."); return; } if (item instanceof Line) _lineCount++; _itemCount = Math.max(_itemCount, item.getID()); _body.add(item); item.setParent(this); _sorted = false; item.setMaxSize(FrameGraphics.getMaxFrameSize()); change(); } } public void setMaxSize(Dimension max) { if (max == null) return; for (Item i : _body) i.setMaxSize(max); _frameName.setPosition(FrameGraphics.getMaxFrameSize().width - _frameName.getBoundsWidth() - Item.MARGIN_RIGHT - org.expeditee.io.Conversion.X_ADJUST, org.expeditee.io.Conversion.Y_ADJUST); } public void addAllItems(List toAdd) { for (Item i : toAdd) addItem(i); } public void removeAllItems(List toRemove) { for (Item i : toRemove) removeItem(i); } public void removeItem(Item item) { if (_body.remove(item)) change(); } /** * Adds the given list of Items to the undo stack. This is the same as * calling addToUndo() for each Item in the list. * * @param items * The List of Items to add to the undo stack. */ public void addAllToUndo(List items) { if (items.size() < 1) return; String id = "" + _undo.size(); for (Item i : items) { i.setData(id); _undo.push(i); } } public void addToUndo(Item item) { if (item == null) return; item.setData("" + _undo.size()); _undo.push(item); } public void undo() { Item undo = null; if (_undo.size() <= 0) return; undo = _undo.pop(); // if the change was to characteristics if (_body.contains(undo)) { Item old = _body.get(_body.indexOf(undo)); _body.set(_body.indexOf(old), undo); // the item was deleted } else { List toRestore = new LinkedList(); toRestore.add(undo); // remove any connected items at the top of the stack while (_undo.size() > 0) { Item next = _undo.peek(); // if this item was connected to one already picked up, remove // it from the stack if (toRestore.contains(next)) _undo.pop(); // else, if this item should be restored (deleted in an enclosed // set) else if (next.getData().equals(undo.getData())) { _undo.pop(); toRestore.add(next); // otherwise, we are done } else break; } // if these items were deleted from a frame, add them addAllItems(toRestore); for (Item i : toRestore) { if (i instanceof Line) { Line line = (Line) i; line.getStartItem().addLine(line); line.getEndItem().addLine(line); } } } change(); FrameGraphics.Repaint(); ItemUtils.EnclosedCheck(_body); } /** * Returns the frameset of this Frame * * @return The name of this Frame's frameset. */ public String getFramesetName() { return _frameset; } public String getFrameName() { return getFramesetNameAdjusted() + _number; } public Item getFrameNameItem() { return _frameName; } /** * Returns the format version of this Frame * * @return The version of this Frame. */ public int getVersion() { return _version; } public int getFormatVersion() { return _fversion; } public String getProtection() { return _protection; } public String getOwner() { return _owner; } public String getDateCreated() { return _creationDate; } public String getLastModifyUser() { return _modifiedUser; } public String getLastModifyDate() { return _modifiedDate; } public String getFrozenDate() { return _frozenDate; } public void setBackgroundColor(Color back) { _background = back; change(); FrameGraphics.Repaint(); } public Color getBackgroundColor() { return _background; } public Color getPaintBackgroundColor() { if (_background == null) return DisplayIO.DEFAULT_BACKGROUND; return _background; } public void setForegroundColor(Color front) { _foreground = front; change(); FrameGraphics.Repaint(); } public Color getForegroundColor() { return _foreground; } public Color getPaintForegroundColor() { final int GRAY = 127; final int THRESHOLD = 10; if (_foreground == null) { Color back = getPaintBackgroundColor(); if (Math.abs(back.getRed() - GRAY) < THRESHOLD && Math.abs(back.getBlue() - GRAY) < THRESHOLD && Math.abs(back.getGreen() - GRAY) < THRESHOLD) return Color.WHITE; Color fore = new Color(Math.abs(255 - back.getRed()), Math .abs(255 - back.getGreen()), Math.abs(255 - back.getBlue())); return fore; // return Item.DEFAULT_FOREGROUND; } return _foreground; } public String toString() { String s = ""; s += "Name: " + _frameset + _number + "\n"; s += "Version: " + _version + "\n"; s += "Format Version: " + _fversion + "\n"; s += "Protection: " + _protection + "\n"; s += "Owner: " + _owner + "\n"; s += "Date Created: " + _creationDate + "\n"; s += "Last Mod. User: " + _modifiedUser + "\n"; s += "Last Mod. Date: " + _modifiedDate + "\n"; s += "Last Froz. Date: " + _frozenDate + "\n"; s += "\n"; s += "\n"; s += "Items: " + _body.size() + "\n"; return s; } public Item getItemAbove(Item current) { int ind = _body.indexOf(current); if (ind == -1) return null; // loop through all items above this one, return the first match for (int i = ind - 1; i >= 0; i--) { Item check = _body.get(i); if (FrameUtils.inSameColumn(check, current)) return check; } return null; } /** * Updates any Images that require it from their ImageObserver (Principally * Animated GIFs) */ public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { FrameGraphics.ForceRepaint(); if (DisplayIO.getCurrentFrame() == this) return true; return false; } /** * Gets the text items that are in the same column and below a specified * item. Frame title and name are excluded from the column list. * * @param from * The Item to get the column for. */ public List getColumn(Item from) { // Check that this item is on the current frame if (!_body.contains(from)) return null; // Make sure the items are sorted Collections.sort(_body); if (from == null) { from = getLastNonAnnotationTextItem(); } if (from == null) return null; /** * TODO: Check */ List column = new ArrayList(); // Create a list of items consisting of the item 'from' and all the // items below it which are also in the same column as it for (int i = _body.indexOf(from); i < _body.size(); i++) { Item item = _body.get(i); if (isNormalTextItem(item)) { if (FrameUtils.inSameColumn(from, item)) column.add(item); } } return column; } /** * Adds the given Frame to the list of overlays Frames being drawn with this * Frame. * * @param overlay * The Frame to add */ public void addOverlay(Overlay overlay) { if (_overlays == null || overlay == null) _overlays = new ArrayList(); _overlays.add(overlay); } /** * Removes the given Frame from the list of overlay Frames being drawn with * this Frame. * * @param overlay * The Frame to remove */ public void removeOverlay(Frame overlay) { _overlays.remove(overlay); FrameGraphics.Repaint(); } public List getOverlays() { return _overlays; } public void clearOverlays() { _overlays.clear(); } public void addAllOverlays(List overlays) { _overlays.addAll(overlays); } @Override public boolean equals(Object o) { if (o instanceof String) { return (String.CASE_INSENSITIVE_ORDER.compare((String) o, getFrameName()) == 0); } if (o instanceof Frame) { return getFrameName().equals(((Frame) o).getFrameName()); } return super.equals(o); } /** * Merge one frames contents into another. * * @param toMergeWith */ private void merge(Frame toMergeWith) { if (toMergeWith == null) return; List copies = ItemUtils.CopyItems(toMergeWith.getItems()); for (Item i : copies) { if (i.getID() >= 0) { i.setID(this.getNextItemID()); addItem(i); } } } /** * TODO document what this method is actually doing and why Merge text?!?! * * @param toMerge * @return the items that cant be merged?!?! */ public List merge(List toMerge) { ArrayList remain = new ArrayList(0); for (Item i : toMerge) { if (!(i instanceof Text)) remain.add(i); else { if (!AttributeUtils.SetAttribute(this, (Text) i)) { if (i.getLink() != null) merge(FrameIO.LoadFrame(i.getAbsoluteLink())); else if (FrameIO .isValidFrameName(((Text) i).getFirstLine())) { merge(FrameIO.LoadFrame(((Text) i).getFirstLine())); } } } } return remain; } /** * Removes all non-title non-annotation items from this Frame. All removed * items are added to the backup-stack. */ public void clear() { List newBody = new ArrayList(0); for (Item i : _body) if (i.isAnnotation() || i == getName() || i == getTitle()) newBody.add(i); _body.removeAll(newBody); addAllToUndo(_body); _body = newBody; } /** * Creates a new Text Item with no text. The newly created Item is a copy * the ItemTemplate if one is present, and inherits all the attributes of * the Template * * @return The newly created Text Item */ public Text createNewText(String text) { Text t = createBlankText(text); t.setText(text); return t; } public Text createBlankText(String templateType) { Text t; if (templateType.length() == 0) t = getItemTemplate().copy(); else t = getItemTemplate(templateType.charAt(0)); // reset attributes t.setID(getNextItemID()); t.setMaxSize(FrameGraphics.getMaxFrameSize()); t.setPosition(DisplayIO.getMouseX(), DisplayIO.getMouseY()); t.setText(""); return t; } private Text getItemTemplate(char firstChar) { switch (firstChar) { case '@': return getAnnotationTemplate(); case '/': return getCodeCommentTemplate(); default: return getItemTemplate(); } } public Text createNewText() { return createNewText(""); } public Text addText(int x, int y, String text, String action) { Text t = createNewText(text); t.setPosition(x, y); t.addAction(action); addItem(t); return t; } public Text addText(int x, int y, String text, String action, String link) { Text t = addText(x, y, text, action); t.setLink(link); return t; } public Dot addDot(int x, int y) { Dot d = new Dot(x, y, getNextItemID()); addItem(d); return d; } /** * Creates a JMenu from the Items present on this Frame and adds it to the * Menus on the Display */ /* * public void createMenu() { for (Item i : _body) { if (ItemUtils.isTag(i, * ItemUtils.TAG_MENU) && i.getLink() != null) { Frame nextMenu = * FrameIO.LoadFrame(i.getLink()); JMenu menu = nextMenu.createSubMenu(); * DisplayIO.addMenu(menu); } } } */ /** * Creates a new JMenu from the Items present on this Frame * * @return The newly created JMenu */ /* * private JMenu createSubMenu() { Text frameTitle = getTitle(); * * if (frameTitle == null) FrameUtils.Parse(this); * * if (frameTitle == null || frameTitle.getFirstLine() == null) return null; * * JMenu menu = new JMenu(frameTitle.getFirstLine()); * * boolean literal = false; String litTitle = null; * * for (Item i : _body) { // if the @lit tag is active if (literal) { * literal = false; if (litTitle == null) litTitle = ((Text) * i).getFirstLine(); JMenuItem item = new JMenuItem(litTitle); * item.addActionListener(new MenuAction(i, true)); menu.add(item); // * non-annotation items with links or actions are put on the // menu } else * if (i != _frameName && i instanceof Text && !i.isAnnotation() && * (i.getLink() != null || i.getAction() != null)) { JMenuItem item = new * JMenuItem(((Text) i).getText().get(0)); item.addActionListener(new * MenuAction(i, false)); menu.add(item); // if this is another menu frame } * else if (i.getLink() != null && ItemUtils.isTag(i, ItemUtils.TAG_MENU)) { * Frame nextMenu = FrameIO.LoadFrame(i.getLink()); * menu.add(nextMenu.createSubMenu()); // if this menu is continued on * another frame } else if (i.getLink() != null && ItemUtils.isTag(i, * ItemUtils.TAG_MENU_NEXT)) { * * Frame nextMenu = FrameIO.LoadFrame(i.getLink()); JMenu nmenu = * nextMenu.createSubMenu(); for(int m = 0; m < nmenu.getComponentCount(); * m++) menu.add(nmenu.getComponent(m)); // if this is a @lit tag, then the * next item is copied } else if (ItemUtils.isTag(i, ItemUtils.TAG_LITERAL)) { * literal = true; String title = ItemUtils.StripTag(((Text) * i).getFirstLine(), ItemUtils.GetTag(ItemUtils.TAG_LITERAL)); if * (title.length() > 0) litTitle = title; else litTitle = null; } } * * return menu; } */ /* * private class MenuAction implements ActionListener { private Item _source = * null; * * private boolean _copy = false; * * public MenuAction(Item source, boolean copy) { _source = source; _copy = * copy; } * * public void actionPerformed(ActionEvent ae) { if (_copy) { Item copy = * _source.copy(); copy.setX(DisplayIO.getMouseX()); * copy.setY(DisplayIO.getMouseY()); FrameMouseActions.pickup(copy); return; } * * if (_source.getAction() != null) { _source.performActions(); } else { * FrameUtils.DisplayFrame(_source.getLink()); } } } */ public boolean isSaved() { return _saved; } public void setSaved() { _saved = true; _change = false; } public static boolean rubberbandingLine() { return FreeItems.size() == 2 && (FreeItems.get(0) instanceof Line || FreeItems.get(1) instanceof Line); } public static boolean itemAttachedToCursor() { return FreeItems.size() > 0; } public static boolean textItemAttachedToCursor() { return itemAttachedToCursor() && FreeItems.get(0) instanceof Text; } public static Item getItemAttachedToCursor() { if (itemAttachedToCursor()) return FreeItems.get(0); return null; } /** * Tests if an item is a non title, non frame name, non special annotation * text item. * * @param it * the item to be tested * @return true if the item is a normal text item */ public boolean isNormalTextItem(Item it) { if (it instanceof Text && it != getTitle() && it != _frameName && !((Text) it).isSpecialAnnotation()) { return true; } return false; } /** * Moves the mouse to the end of the text item with a specified index. * * @param index */ public boolean moveMouseToTextItem(int index) { List items = getItems(); int itemsFound = 0; for (int i = 0; i < items.size(); i++) { Item it = items.get(i); if (isNormalTextItem(it)) itemsFound++; if (itemsFound > index) { DisplayIO.setCursorPosition(((Text) it) .getEndParagraphPosition().x, it.getY()); DisplayIO.resetCursorOffset(); FrameGraphics.Repaint(); return true; } } return false; } /* * public boolean moveMouseToNextTextItem(int index) { List items = * getItems(); int itemsFound = 0; for (int i = 0; i < items.size(); i++) { * Item it = items.get(i); if ( isNormalTextItem(it)) itemsFound++; if * (itemsFound > index) { * DisplayIO.setCursorPosition(((Text)it).getEndParagraphPosition().x, * it.getY()); DisplayIO.resetCursorOffset(); FrameGraphics.Repaint(); * return true; } } * * return false; } */ /** * Searches for an annotation item called start to be used as the default * cursor location when TDFC occurs. */ public boolean moveMouseToDefaultLocation() { List items = getItems(); for (Item it : items) { if (it instanceof Text) { Text t = (Text) it; if (t.getTextNoList().toLowerCase().startsWith("@start:") || t.getTextNoList().toLowerCase().equals("@start")) { t.stripFirstWord(); if (t.getTextNoList().equals("")) DisplayIO.getCurrentFrame().removeItem(t); if (!Frame.itemAttachedToCursor()) { DisplayIO.setCursorPosition(((Text) it) .getEndParagraphPosition()); DisplayIO.resetCursorOffset(); } FrameGraphics.Repaint(); return true; } } } return false; } /** * Gets the file name that actions should use to export files created by * running actions from this frame. * * @return the fileName if the frame contains an '@file' tag. Returns the * name of the frame if the tag isnt on the frame. */ public String getExportFileName() { Text tag = ItemUtils.FindTag(getItems(), "@file:"); if (tag != null) { String file = ItemUtils.StripTag(tag.getFirstLine(), "@file:"); file = file.trim(); if (file.length() > 0) return file; } return _frameName.getTextNoList(); } public void toggleBackgroundColor() { setBackgroundColor(ColorUtils.getNextColor(_background, Frame.COLOR_WHEEL)); } }