source: trunk/src/org/expeditee/gui/FrameCreator.java@ 1505

Last change on this file since 1505 was 1505, checked in by bnemhaus, 4 years ago

New Attributes (and repurposed old ones) to be used for encryption of frames:

  • FrameEncryptionLabel. Used to be EncryptionLabel, which is still the case for items. When applied to a frame, it determines the label used to encrypt the entire frame.
  • HomogeneousEncryptionLabel. Does not yet actually do anything. The future point of this attribute is to provide the label that must be used to encrypt items on the frame when the user has only homogeneous encryption permissions.
  • EncryptionFramePermission. Does not yet actually do anything. The future point of this attribute isto determine if a user is able to change the FrameEncryptionLabel on a frame. Level 0 (none), no they cannot. Level 1 (homogeneous), they can only change it to HomogeneousEncryptionLabel. Level 2 (Hetrogeneous Owner), they can change it to any label as long as the owner of the Frame has that label. Level 3 (Hetrogeneous), they can change it to anything.
  • EncryptionPermission. Does not yet actually do anything. The future point of this attribute is to determine what encryption labels can be applied to items on the frame. Level 0 (none), cannot apply an encryption label. Level 1 (homogeneous), they can only used the label specified in HomogeneousEncryptionLabel. Level 2 (Hetrogeneous Owner), they can only use encryption labels that the owner of the frame has. Level 3 (Hetrogeneous) they can use any labels to encrypt an item.
File size: 11.7 KB
Line 
1/**
2 * FrameCreator.java
3 * Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package org.expeditee.gui;
20
21import java.io.File;
22import java.io.IOException;
23import java.nio.file.Files;
24import java.nio.file.Path;
25import java.nio.file.Paths;
26import java.util.Collection;
27import java.util.Comparator;
28import java.util.LinkedList;
29import java.util.List;
30import java.util.Optional;
31
32import org.expeditee.agents.ExistingFramesetException;
33import org.expeditee.agents.InvalidFramesetNameException;
34import org.expeditee.core.Colour;
35import org.expeditee.items.Item;
36import org.expeditee.items.Text;
37
38public class FrameCreator {
39
40 public static final int INDENT_FROM_TITLE = 20;
41
42 private int START_Y;
43
44 private int START_X;
45
46 private Frame _current = null;
47
48 private int _lastX;
49
50 private int _maxX = 0;
51
52 private int _lastY;
53
54 // Master copy of next & previous links
55 private Item _Mnext;
56
57 private Item _Mprev;
58
59 private Item _Mfirst;
60
61 private Frame _firstFrame;
62
63 private boolean _multiColumn;
64
65 public enum ExistingFramesetOptions {
66 /**
67 * Do not attempt to use any existing frames in specified framesets.
68 */
69 AppendSegregatedFrames,
70 /**
71 * Override any existing frames in specified framesets.
72 */
73 OverrideExistingFrames,
74 /**
75 * Use the existing frames in the framesets to reobtain what the state of the
76 * FrameCreator should be.
77 */
78 AppendAfterLastItem
79 }
80
81 private final List<Frame> framesCreated = new LinkedList<Frame>();
82
83 private String encryptionLabel;
84
85 public FrameCreator(String frameTitle) {
86 this(DisplayController.getCurrentFrame().getFramesetName(), DisplayController.getCurrentFrame().getPath(),
87 frameTitle, ExistingFramesetOptions.AppendSegregatedFrames, false, null);
88 }
89
90 public FrameCreator(String framesetName, String path, String frameTitle, ExistingFramesetOptions establishState, boolean multiColumn, String encryptionLabel) {
91 this.encryptionLabel = encryptionLabel;
92 switch (establishState) {
93 case OverrideExistingFrames:
94 try {
95 FrameIO.SuspendCache();
96 Path framesetDir = Files.createTempDirectory("temporaryExpediteeFrameset");
97 initialise(framesetName, framesetDir.toAbsolutePath(), frameTitle, multiColumn);
98 FrameIO.EnableCache();
99 FrameIO.deleteFrameset(framesetName);
100 FrameIO.moveFrameset(framesetName, framesetDir.toAbsolutePath().toString() + File.separator, path, true);
101 _current.setPath(path);
102 framesetDir.toFile().deleteOnExit();
103 } catch (IOException e) {
104 e.printStackTrace();
105 }
106 break;
107 case AppendSegregatedFrames:
108 initialise(framesetName, Paths.get(path), frameTitle, multiColumn);
109 break;
110 case AppendAfterLastItem:
111 initialiseReobtainState(framesetName, Paths.get(path), frameTitle, multiColumn);
112 break;
113 }
114 }
115
116 private void initialiseReobtainState(String framesetName, Path path, String frameTitle, boolean multiColumn) {
117 _multiColumn = multiColumn;
118 _Mnext = createButton("@Next", null, null, 10, 15);
119 _Mprev = createButton("@Previous", null, null, _Mnext.getBoundsWidth() + _Mnext.getAnchorRight() + 20, 15);
120 _Mfirst = createButton("@First", null, null, _Mprev.getBoundsWidth() + _Mprev.getAnchorRight() + 20, 15);
121
122 int lastNumber = FrameIO.getLastNumber(framesetName);
123 for (int i = 1; i <= lastNumber; i++) {
124 Frame frame = FrameIO.LoadFrame(framesetName + i, path.toAbsolutePath().toString() + File.separator);
125 this.framesCreated.add(frame);
126 }
127 if (this.framesCreated.isEmpty()) {
128 initialise(framesetName, path, frameTitle, multiColumn);
129 return;
130 }
131 _firstFrame = this.framesCreated.get(0);
132 _current = this.framesCreated.get(this.framesCreated.size() - 1);
133
134 Collection<Text> allExistingTextItems = _current.getTextItems();
135 allExistingTextItems.remove(_Mfirst);
136 allExistingTextItems.remove(_Mnext);
137 allExistingTextItems.remove(_Mprev);
138 Optional<Text> maxByY = allExistingTextItems.stream().max(new Comparator<Text>() {
139 @Override
140 public int compare(Text t1, Text t2) {
141 return t1.getY() - t2.getY();
142 }
143 });
144 if (maxByY.isPresent()) {
145 Text lowest = maxByY.get();
146 _lastY = lowest.getY() + lowest.getBoundsHeight() / 2;
147 }
148 Optional<Text> maxByX = allExistingTextItems.stream().max(new Comparator<Text>() {
149 @Override
150 public int compare(Text t1, Text t2) {
151 return t1.getX() - t2.getX();
152 }
153 });
154 if (maxByX.isPresent()) {
155 Text furthest = maxByX.get();
156 _lastX = furthest.getX();
157 }
158 }
159
160 private void initialise(String framesetName, Path path, String frameTitle, boolean multiColumn) {
161 _multiColumn = multiColumn;
162 _Mnext = createButton("@Next", null, null, 10, 15);
163 _Mprev = createButton("@Previous", null, null, _Mnext.getBoundsWidth() + _Mnext.getAnchorRight() + 20, 15);
164 _Mfirst = createButton("@First", null, null, _Mprev.getBoundsWidth() + _Mprev.getAnchorRight() + 20, 15);
165
166 try {
167 Frame toUse;
168 if (FrameIO.canAccessFrameset(framesetName, path)) {
169 toUse = FrameIO.CreateFrame(framesetName, frameTitle, null);
170 } else {
171 toUse = FrameIO.CreateFrameset(framesetName, path.toAbsolutePath().toString() + File.separator, true);
172 }
173
174 if (encryptionLabel != null && encryptionLabel.length() > 0) {
175 toUse.setFrameEncryptionLabel(encryptionLabel);
176 }
177
178 this.framesCreated.add(toUse);
179 resetGlobals(toUse);
180 _firstFrame = toUse;
181 } catch (InvalidFramesetNameException e) {
182 e.printStackTrace();
183 } catch (ExistingFramesetException e) {
184 // This should never happen as we are allowing for an override of existing frameset.
185 }
186 }
187
188 /**
189 * Creates a text item that looks like a clickable button.
190 *
191 * @param text
192 * the caption for the button
193 * @param x
194 * the x position for the button. Null if the button is anchored to
195 * the right of the screen.
196 * @param y
197 * the y position for the button. Null if the button is anchored to
198 * the bottom of the screen.
199 * @param right
200 * the distance the button is anchored from the right of this screen.
201 * Null if an absolute position is used.
202 * @param bottom
203 * the distance the button is to be anchored from the bottom of the
204 * screen. Null if the button is given an absolute position.
205 * @return the newly created button.
206 */
207 public static Item createButton(String text, Integer x, Integer y, Integer right, Integer bottom) {
208 Text button = new Text(text);
209
210 button.setBackgroundColor(Colour.LIGHT_GREY);
211 button.setBorderColor(Colour.DARK_GREY);
212 button.setThickness(2.0F);
213 if (bottom != null)
214 button.setAnchorBottom(bottom);
215 if (x != null)
216 button.setX(x);
217 if (right != null)
218 button.setAnchorRight(right);
219 if (y != null)
220 button.setY(y);
221
222 button.invalidateBounds();
223
224 return button;
225 }
226
227 public String getName() {
228 return _firstFrame.getName();
229 }
230
231 /**
232 * Creates the next frame in the frameset, with a previous button already added
233 * and linked to the last frame. _current then gets updated to point at the
234 * newly created Frame, and _lastY is reset
235 */
236 public boolean createNextFrame() {
237 try {
238 Frame newFrame = FrameIO.CreateFrame(_current.getFramesetName(), _current.getTitle(), null);
239
240 this.framesCreated.add(newFrame);
241
242 // add link to previous frame
243 // _prev =
244 addPreviousButton(newFrame, _current.getName());
245
246 // add link to new frame
247 // _next =
248 addNextButton(_current, newFrame.getName());
249
250 // add link to new frame
251 addFirstButton(newFrame, _firstFrame.getName());
252
253 if (encryptionLabel != null && encryptionLabel.length() > 0) {
254 newFrame.setFrameEncryptionLabel(encryptionLabel);
255 }
256
257 FrameIO.SaveFrame(_current, false);
258
259 resetGlobals(newFrame);
260 _maxX = 0;
261 return true;
262 } catch (Exception e) {
263 return false;
264 }
265 }
266
267 public List<Frame> getFramesCreated() {
268 return this.framesCreated;
269 }
270
271 private void resetGlobals(Frame toUse) {
272 Text title = toUse.getTitleItem();
273 START_X = INDENT_FROM_TITLE + title.getX();
274 START_Y = getYStart(title);
275 _lastY = START_Y;
276 _lastX = START_X;
277 // Check for @Start
278 for (Item it : toUse.getSortedItems()) {
279 if (it instanceof Text) {
280 Text t = (Text) it;
281 if (t.getText().toLowerCase().equals("@start") || t.getText().toLowerCase().startsWith("@start:")) {
282 t.stripFirstWord();
283
284 if (t.getText().equals("")) {
285 _lastY = t.getY();
286 _lastX = t.getX();
287 t.delete();
288 break;
289 }
290 }
291 }
292 }
293 _current = toUse;
294 }
295
296 public boolean addItem(Item toAdd, boolean bSave) {
297 try {
298 // if we have reached the end of the Y axis, try moving over on the
299 // X axis
300 if (_lastY >= _Mprev.getY() - _Mprev.getBoundsHeight()) {
301 _lastX = _maxX + 10;
302 _lastY = START_Y;
303
304 // if there is no more room on the X axis, we have to start a
305 // new frame
306 if (!_multiColumn || toAdd.getBoundsWidth() + _lastX > DisplayController.getFramePaintAreaWidth()) {
307 // Make sure text items that are created on the current
308 // frame are removed
309 _current.removeItem(toAdd);
310 createNextFrame();
311 }
312 }
313
314 toAdd.setPosition(_lastX, _lastY + toAdd.getBoundsHeight() / 2);
315 toAdd.setOffset(0, 0);
316 toAdd.setID(_current.getNextItemID());
317 toAdd.setRightMargin(DisplayController.getFramePaintAreaWidth(), true);
318
319 _current.addItem(toAdd);
320
321 _lastY = toAdd.getY() + toAdd.getBoundsHeight() / 2;
322 _maxX = Math.max(toAdd.getX() + toAdd.getBoundsWidth(), _maxX);
323
324 if (bSave)
325 save();
326
327 return true;
328 } catch (Exception e) {
329 return false;
330 }
331 }
332
333 public Text addText(String toAdd, Colour c, String link, String action, boolean bSave) {
334 Text text = _current.createNewText(toAdd);
335 if (c != null)
336 text.setColor(c);
337 text.setLink(link);
338 text.setAction(action);
339
340 addItem(text, bSave);
341
342 return text;
343 }
344
345 public void save() {
346 FrameIO.ForceSaveFrame(_current);
347 }
348
349 public int getLastY() {
350 return _lastY;
351 }
352
353 public void setLastY(int lastY) {
354 _lastY = lastY;
355 }
356
357 public Frame getCurrentFrame() {
358 return _current;
359 }
360
361 /**
362 * Returns the Frame name of the current frame for the FrameCreator
363 *
364 * @return The current frame for the FrameCreator
365 */
366 public String getCurrent() {
367 if (_current == null)
368 return null;
369
370 return _current.getName();
371 }
372
373 public Frame getFirstFrame() {
374 return _firstFrame;
375 }
376
377 public Item addNextButton(Frame current, String link) {
378 return addButton(_Mnext, current, link);
379 }
380
381 public Item addPreviousButton(Frame current, String link) {
382 return addButton(_Mprev, current, link);
383 }
384
385 public Item addFirstButton(Frame current, String link) {
386 return addButton(_Mfirst, current, link);
387 }
388
389 public Item addButton(Item template, Frame current, String link) {
390 // add link to new frame
391 Item previousButton = template.copy();
392 previousButton.setID(current.getNextItemID());
393 previousButton.setLink(link);
394 previousButton.setLinkHistory(false);
395 previousButton.setLinkMark(false);
396 // previousButton.setPermission(new
397 // PermissionPair(UserAppliedPermission.followLinks));
398 current.addItem(previousButton);
399
400 return previousButton;
401 }
402
403 public void addSpace(int space) {
404 _lastY += space;
405 }
406
407 public static int getYStart(Item title) {
408 return title.getY() + title.getBoundsHeight();
409 }
410
411 public void setTitle(String titleText) {
412 _current.setTitle(titleText);
413 }
414}
Note: See TracBrowser for help on using the repository browser.