source: trunk/src/org/expeditee/agents/Format.java@ 427

Last change on this file since 427 was 427, checked in by ra33, 15 years ago
File size: 5.6 KB
Line 
1package org.expeditee.agents;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.Collections;
6import java.util.Comparator;
7import java.util.HashSet;
8import java.util.List;
9
10import org.expeditee.gui.Frame;
11import org.expeditee.gui.FrameGraphics;
12import org.expeditee.gui.FrameUtils;
13import org.expeditee.items.Item;
14import org.expeditee.items.Text;
15
16/**
17 * A simple formatting agent that aligns all non-annotation Items on the given
18 * Frame by the X and Y axis of the first Item on the Frame. This agent
19 * separates the items into columns, the actual alignment is done by
20 * FrameUtils.Align()
21 *
22 * @author jdm18
23 *
24 */
25public class Format extends DefaultAgent {
26 // whether the Items could be formatted successfully
27 private boolean _success = true;
28
29 // adjustmen from the default format spacing
30 private int _adjust = 0;
31
32 public Format() {
33 super();
34 }
35
36 public Format(String param) {
37 try {
38 if (param.startsWith("+"))
39 param = param.substring(1);
40 _adjust = Integer.parseInt(param);
41 } catch (Exception e) {
42 e.printStackTrace();
43 }
44 }
45
46 @Override
47 public Frame process(Frame start) {
48 // TODO What will happen if user runs the SIMPLE form of this...
49 // Does format box need to be disabled?!?!
50 // Check the position of the cursor and only format stuff inside the
51 // same box as the cursor
52 Collection<Text> itemsToFormat = getItemsToFormat(start);
53
54 ArrayList<Item> columnHeads = new ArrayList<Item>();
55
56 ArrayList<ArrayList<Text>> columns = new ArrayList<ArrayList<Text>>();
57
58 for (Text t : itemsToFormat) {
59 int col = findColumn(columnHeads, t);
60 // if this is the head of a new column
61 if (col < 0) {
62 columnHeads.add(t);
63 columns.add(new ArrayList<Text>());
64 // otherwise the column for this item has already been
65 // found set the column to be the one we just added...
66 col = columns.size() - 1;
67 } else
68 columns.get(col).add(t);
69 }
70
71 // check for empty columns
72 int[] clear = new int[columnHeads.size()];
73 for (int i = 0; i < columns.size(); i++)
74 clear[i] = columns.get(i).size();
75
76 // remove empty columns
77 for (int i = (clear.length - 1); i >= 0; i--)
78 if (clear[i] == 0) {
79 columns.remove(i);
80 columnHeads.remove(i);
81 }
82
83 // if there are no columns to align, we are done
84 if (columns.size() == 0)
85 return null;
86
87 // sort the column heads by X position
88 Collections.sort(columnHeads, new Comparator<Item>() {
89 public int compare(Item o1, Item o2) {
90 return o1.getX() - o2.getX();
91 }
92
93 });
94
95 // sort lists by their X axis
96 Collections.sort(columns, new Comparator<ArrayList<Text>>() {
97 public int compare(ArrayList<Text> o1, ArrayList<Text> o2) {
98 if (o2.size() == 0)
99 return -10;
100
101 if (o1.size() == 0)
102 return 10;
103
104 Item i1 = o1.get(0);
105 Item i2 = o2.get(0);
106
107 return (i1.getX() - i2.getX());
108 }
109
110 });
111
112 int res = FrameUtils.Align(columns.get(0), true, _adjust);
113 _success = _success && (res >= 0);
114
115 for (int i = 0; i < columns.size() - 1; i++) {
116 List<Text> list = columns.get(i);
117
118 int maxX = 0;
119 int maxY = 0;
120 for (Item it : list) {
121 maxX = Math.max(maxX, it.getX() + it.getBoundsWidth());
122 maxY = Math.max(maxY, it.getY() + it.getBoundsHeight());
123 }
124
125 int xCheck = maxX;
126 for (Item it : columns.get(i + 1))
127 xCheck = Math.max(xCheck, maxX
128 + /* item.getX() + */it.getBoundsWidth());
129
130 if (xCheck < FrameGraphics.getMaxSize().width) {
131 if (columnHeads.get(i + 1).getX() < maxX
132 && columnHeads.get(i + 1).getY() < maxY)
133 columnHeads.get(i + 1).setX(maxX);
134
135 for (Item it : columns.get(i + 1))
136 if (it.getX() < maxX && it.getY() < maxY)
137 it.setX(maxX);
138 }
139
140 res = FrameUtils.Align(columns.get(i + 1), true, _adjust);
141 _success = _success && (res >= 0);
142 }
143
144 // align all the separate columns
145 /*
146 * for(ArrayList<Item> l : columns){ int res = FrameUtils.Align(l,
147 * true); _success = _success && (res >= 0); }
148 */
149 start.setChanged(true);
150 FrameGraphics.requestRefresh(true);
151 return null;
152 }
153
154 /**
155 * Finds which column contains the given Item, and returns the index to the
156 * column in the start & end lists. Returns -1 if no column is found that
157 * contains the given Item.
158 *
159 * @param toFind
160 * The Item to determine the correct column for
161 * @return The index of the column in the lists, or -1 if no column is found
162 */
163 private int findColumn(ArrayList<Item> columnHeads, Item toFind) {
164 for (Item top : columnHeads)
165 if (FrameUtils.inSameColumn(top, toFind))
166 return columnHeads.indexOf(top);
167
168 return -1;
169 }
170
171 @Override
172 protected void finalise(Frame start) {
173 if (_success)
174 overwriteMessage("Formatting complete.");
175 }
176
177 @Override
178 protected void message(String message) {
179 }
180
181 @Override
182 protected void overwriteMessage(String message) {
183 }
184
185 /**
186 * Gets all the items that need to be formatted. If the user clicks in
187 * freeSpace these are all items not enclosed by a rectangle. If the user is
188 * formatting the items in a rectangle this is all the items in the
189 * rectangle.
190 *
191 * @param start
192 */
193 protected Collection<Text> getItemsToFormat(Frame start) {
194 Collection<Text> itemsToFormat = FrameUtils.getCurrentTextItems();
195
196 // If the cursor is not inside a box...
197 if (itemsToFormat.size() < 1) {
198 // Add all the items that are in free space
199 itemsToFormat = start.getBodyTextItems(true);
200 // Remove all the enclosed items
201 Collection<Item> seen = new HashSet<Item>();
202 for (Item i : start.getVisibleItems()) {
203 if (!seen.contains(i) && i.isEnclosed()) {
204 seen.addAll(i.getEnclosingDots());
205 itemsToFormat.removeAll(i.getEnclosedItems());
206 }
207 }
208 }
209 return itemsToFormat;
210 }
211
212}
Note: See TracBrowser for help on using the repository browser.