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

Last change on this file since 376 was 376, checked in by ra33, 16 years ago
File size: 5.2 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 = FrameUtils.getCurrentTextItems();
53
54 // If the cursor is not inside a box...
55 if (itemsToFormat.size() < 1) {
56 // Add all the items that are in free space
57 itemsToFormat = start.getBodyTextItems(true);
58 // Remove all the enclosed items
59 Collection<Item> seen = new HashSet<Item>();
60 for (Item i : start.getVisibleItems()) {
61 if (!seen.contains(i) && i.isEnclosed()) {
62 seen.addAll(i.getEnclosingDots());
63 itemsToFormat.removeAll(i.getEnclosedItems());
64 }
65 }
66 }
67
68 ArrayList<Item> columnHeads = new ArrayList<Item>();
69
70 ArrayList<ArrayList<Text>> columns = new ArrayList<ArrayList<Text>>();
71
72 for (Text t : itemsToFormat) {
73 int col = findColumn(columnHeads, t);
74 // if this is the head of a new column
75 if (col < 0) {
76 columnHeads.add(t);
77 columns.add(new ArrayList<Text>());
78 // otherwise the column for this item has already been
79 // found set the column to be the one we just added...
80 col = columns.size() - 1;
81 } else
82 columns.get(col).add(t);
83 }
84
85 // check for empty columns
86 int[] clear = new int[columnHeads.size()];
87 for (int i = 0; i < columns.size(); i++)
88 clear[i] = columns.get(i).size();
89
90 // remove empty columns
91 for (int i = (clear.length - 1); i >= 0; i--)
92 if (clear[i] == 0) {
93 columns.remove(i);
94 columnHeads.remove(i);
95 }
96
97 // if there are no columns to align, we are done
98 if (columns.size() == 0)
99 return null;
100
101 // sort the column heads by X position
102 Collections.sort(columnHeads, new Comparator<Item>() {
103 public int compare(Item o1, Item o2) {
104 return o1.getX() - o2.getX();
105 }
106
107 });
108
109 // sort lists by their X axis
110 Collections.sort(columns, new Comparator<ArrayList<Text>>() {
111 public int compare(ArrayList<Text> o1, ArrayList<Text> o2) {
112 if (o2.size() == 0)
113 return -10;
114
115 if (o1.size() == 0)
116 return 10;
117
118 Item i1 = o1.get(0);
119 Item i2 = o2.get(0);
120
121 return (i1.getX() - i2.getX());
122 }
123
124 });
125
126 int res = FrameUtils.Align(columns.get(0), true, _adjust);
127 _success = _success && (res >= 0);
128
129 for (int i = 0; i < columns.size() - 1; i++) {
130 List<Text> list = columns.get(i);
131
132 int maxX = 0;
133 int maxY = 0;
134 for (Item it : list) {
135 maxX = Math.max(maxX, it.getX() + it.getBoundsWidth());
136 maxY = Math.max(maxY, it.getY() + it.getBoundsHeight());
137 }
138
139 int xCheck = maxX;
140 for (Item it : columns.get(i + 1))
141 xCheck = Math.max(xCheck, maxX
142 + /* item.getX() + */it.getBoundsWidth());
143
144 if (xCheck < FrameGraphics.getMaxSize().width) {
145 if (columnHeads.get(i + 1).getX() < maxX
146 && columnHeads.get(i + 1).getY() < maxY)
147 columnHeads.get(i + 1).setX(maxX);
148
149 for (Item it : columns.get(i + 1))
150 if (it.getX() < maxX && it.getY() < maxY)
151 it.setX(maxX);
152 }
153
154 res = FrameUtils.Align(columns.get(i + 1), true, _adjust);
155 _success = _success && (res >= 0);
156 }
157
158 // align all the separate columns
159 /*
160 * for(ArrayList<Item> l : columns){ int res = FrameUtils.Align(l,
161 * true); _success = _success && (res >= 0); }
162 */
163 start.setChanged(true);
164 FrameGraphics.requestRefresh(true);
165 return null;
166 }
167
168 /**
169 * Finds which column contains the given Item, and returns the index to the
170 * column in the start & end lists. Returns -1 if no column is found that
171 * contains the given Item.
172 *
173 * @param toFind
174 * The Item to determine the correct column for
175 * @return The index of the column in the lists, or -1 if no column is found
176 */
177 private int findColumn(ArrayList<Item> columnHeads, Item toFind) {
178 for (Item top : columnHeads)
179 if (FrameUtils.inSameColumn(top, toFind))
180 return columnHeads.indexOf(top);
181
182 return -1;
183 }
184
185 @Override
186 protected void finalise(Frame start) {
187 if (_success)
188 overwriteMessage("Formatting complete.");
189 }
190
191 @Override
192 protected void message(String message) {
193 }
194
195 @Override
196 protected void overwriteMessage(String message) {
197 }
198
199}
Note: See TracBrowser for help on using the repository browser.