source: trunk/src/org/expeditee/settings/Settings.java@ 1415

Last change on this file since 1415 was 1415, checked in by bln4, 5 years ago

Renamed Frame.getItems() to Frame.getSortedItems() to better represent its functionality.

-> org.apollo.ApolloGestureActions
-> org.apollo.ApolloSystem
-> org.expeditee.actions.Actions
-> org.expeditee.actions.Debug
-> org.expeditee.actions.ExploratorySearchActions
-> org.expeditee.actions.JfxBrowserActions
-> org.expeditee.actions.Misc
-> org.expeditee.actions.Navigation
-> org.expeditee.actions.ScriptBase
-> org.expeditee.actions.Simple
-> org.expeditee.agents.ComputeTree
-> org.expeditee.agents.CopyTree
-> org.expeditee.agents.DisplayComet
-> org.expeditee.agents.DisplayTree
-> org.expeditee.agents.DisplayTreeLeaves
-> org.expeditee.agents.GraphFramesetLinks
-> org.expeditee.agents.TreeProcessor
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gui.DisplayController
-> org.expeditee.gui.FrameCreator
-> org.expeditee.gui.FrameIO
-> org.expeditee.io.DefaultTreeWriter
-> org.expeditee.io.JavaWriter
-> org.expeditee.io.PDF2Writer
-> org.expeditee.io.TXTWriter
-> org.expeditee.io.WebParser
-> org.expeditee.io.flowlayout.XGroupItem
-> org.expeditee.items.Dot
-> org.expeditee.items.Item
-> org.expeditee.items.ItemUtils
-> org.expeditee.network.FrameShare
-> org.expeditee.stats.TreeStats


Created ItemsList class to wrap ArrayList<Item>. Frames now use this new class to store its body list (used for display) as well as its primaryBody and surrogateBody.

-> org.expeditee.agents.Format
-> org.expeditee.agents.HFormat
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gui.Frame
-> org.expeditee.gui.FrameUtils


Refactorted Frame.setResort(bool) to Frame.invalidateSorted() to better function how it is intended to with a more accurate name.

-> org.expeditee.agents.Sort


When writing out .exp files and getting attributes to respond to LEFT + RIGHT click, boolean items are by default true. This has always been the case. An ammendment to this is that defaults can now be established.
Also added 'EnterClick' functionality. If cursored over a item with this property and you press enter, it acts as if you have clicked on it instead.

-> org.expeditee.assets.resources-public.framesets.authentication.1.exp to 6.exp
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gio.input.KBMInputEvent
-> org.expeditee.gio.javafx.JavaFXConversions
-> org.expeditee.gio.swing.SwingConversions
-> org.expeditee.gui.AttributeUtils
-> org.expeditee.io.Conversion
-> org.expeditee.io.DefaultFrameWriter
-> org.expeditee.items.Item


Fixed a bug caused by calling Math.abs on Integer.MIN_VALUE returning unexpected result. Due to zero being a thing, you cannot represent Math.abs(Integer.MIN_VALUE) in a Integer object. The solution is to use Integer.MIN_VALUE + 1 instead of Integer.MIN_VALUE.

-> org.expeditee.core.bounds.CombinationBounds
-> org.expeditee.io.flowlayout.DimensionExtent


Recoded the contains function in EllipticalBounds so that intersection tests containing circles work correctly.

-> org.expeditee.core.bounds.EllipticalBounds


Added toString() to PolygonBounds to allow for useful printing during debugging.

-> org.expeditee.core.bounds.PolygonBounds

Implemented Surrogate Mode!

-> org.expeditee.encryption.io.EncryptedExpReader
-> org.expeditee.encryption.io.EncryptedExpWriter
-> org.expeditee.encryption.items.surrogates.EncryptionDetail
-> org.expeditee.encryption.items.surrogates.Label
-> org.expeditee.gui.FrameUtils
-> org.expeditee.gui.ItemsList
-> org.expeditee.items.Item
-> org.expeditee.items.Text


???? Use Integer.MAX_VALUE cast to a float instead of Float.MAX_VALUE. This fixed some bug which I cannot remember.

-> org.expeditee.gio.TextLayoutManager
-> org.expeditee.gio.swing.SwingTextLayoutManager


Improved solution for dealing with the F10 key taking focus away from Expeditee due to it being a assessibility key.

-> org.expeditee.gio.swing.SwingInputManager


Renamed variable visibleItems in FrameGraphics.paintFrame to itemsToPaintCanditates to better represent functional intent.

-> org.expeditee.gui.FrameGraphics


Improved checking for if personal resources exist before recreating them

-> org.expeditee.gui.FrameIO


Repeated messages to message bay now have a visual feedback instead of just a beep. This visual feedback is in the form of a count of the amount of times it has repeated.

-> org.expeditee.gui.MessageBay


Updated comment on the Vector class to explain what vectors are.

-> org.expeditee.gui.Vector


Added constants to represent all of the property keys in DefaultFrameReader and DefaultFrameWriter.

-> org.expeditee.io.DefaultFrameReader
-> org.expeditee.io.DefaultFrameWriter


Updated the KeyList setting to be more heirarcial with how users will store their Secrets.

-> org.expeditee.settings.identity.secrets.KeyList

File size: 11.0 KB
Line 
1/**
2 * Settings.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.settings;
20
21import java.lang.reflect.Field;
22import java.lang.reflect.Method;
23import java.util.Collection;
24import java.util.HashMap;
25import java.util.Iterator;
26import java.util.LinkedList;
27import java.util.List;
28
29import org.expeditee.gui.AttributeValuePair;
30import org.expeditee.gui.Frame;
31import org.expeditee.gui.FrameCreator;
32import org.expeditee.gui.MessageBay;
33import org.expeditee.items.Item;
34import org.expeditee.items.ItemParentStateChangedEvent;
35import org.expeditee.items.Text;
36import org.expeditee.items.widgets.Password;
37import org.expeditee.reflection.PackageLoader;
38import org.expeditee.setting.Setting;
39import org.expeditee.setting.VariableSetting;
40
41public abstract class Settings {
42
43 public static final String SETTINGS_PACKAGE_PARENT = "org.expeditee.";
44 public static final String SETTINGS_PACKAGE = SETTINGS_PACKAGE_PARENT + "settings.";
45
46 private static final class PageDescriptor {
47
48 private final HashMap<String, Setting> settings = new HashMap<String, Setting>();
49 private final List<String> orderedEntries = new LinkedList<String>();
50 private final List<VariableSetting> settingsList = new LinkedList<VariableSetting>();
51 private final Method onParsed;
52
53 private PageDescriptor(Class<?> clazz) {
54
55 // populate map of settings
56 for(Field f : clazz.getFields()) {
57 // Only allow classes that inherit from Setting
58 if(!Setting.class.isAssignableFrom(f.getType())) continue;
59
60 try {
61 Setting s = (Setting) f.get(null);
62 settings.put(f.getName().toLowerCase(), s);
63 if (s instanceof VariableSetting) settingsList.add((VariableSetting) s);
64 orderedEntries.add(f.getName());
65 } catch (Exception e) {
66 e.printStackTrace();
67 }
68 }
69
70 Method m = null;
71
72 try {
73 m = clazz.getMethod("onParsed", Text.class);
74 } catch(Exception e) {
75 // System.err.println(clazz.getName() + " has no onParsed(Text t) callback");
76 }
77
78 this.onParsed = m;
79 }
80 }
81
82 private static HashMap<String, PageDescriptor> _pages = new HashMap<String, PageDescriptor>();
83
84 private static boolean _init = false;
85
86 public static void Init()
87 {
88 if(_init) return;
89
90 _init = true;
91
92 try {
93 for(Class<?> clazz : PackageLoader.getClassesNew(SETTINGS_PACKAGE)) {
94 // Ignore this class since it's the controller
95 if(clazz.equals(Settings.class)) continue;
96
97 String settingsPageName = clazz.getPackage().getName().toLowerCase().substring(SETTINGS_PACKAGE_PARENT.length());
98
99 // System.out.println(settingsPage + " : " + clazz.getName());
100 _pages.put(settingsPageName, new PageDescriptor(clazz));
101 }
102
103 } catch (Exception e) {
104 e.printStackTrace();
105 }
106 }
107
108 /** Parses the settings tree, then resets any settings that were not set. */
109 public static void parseSettings(Text text)
110 {
111 List<VariableSetting> set = parseSettings(text, "");
112 List<VariableSetting> toDefault = new LinkedList<VariableSetting>();
113
114 for(PageDescriptor pd : _pages.values()) toDefault.addAll(pd.settingsList);
115
116 toDefault.removeAll(set);
117
118 for(VariableSetting s : toDefault) {
119 try {
120 s.reset();
121 } catch (Exception e) {
122 e.printStackTrace();
123 }
124 }
125 }
126
127 public static void resetAllSettings() {
128 for (PageDescriptor pd : _pages.values()) {
129 for (VariableSetting s : pd.settingsList) {
130 s.reset();
131 }
132 }
133 }
134
135 /**
136 * Sets all the simple settings.
137 *
138 * @param text
139 * @param prefix
140 *
141 * @return List of VariableSettings that were changed
142 */
143 private static List<VariableSetting> parseSettings(Text text, String prefix) {
144
145 List<VariableSetting> set = new LinkedList<VariableSetting>();
146
147 Frame child = text.getChild();
148
149 if(child == null) return set;
150
151 String settingsPage = prefix + text.getText().trim().toLowerCase().replaceAll("^@", "");
152 PageDescriptor pd = _pages.get(settingsPage);
153 if(pd == null) return set;
154
155 try {
156 // set the fields
157 List<Text> items = child.getBodyTextItems(false);
158 List<Text> annotations = new LinkedList<Text>(child.getAnnotationItems());
159 List<Frame> seen = new LinkedList<Frame>(); // to avoid getting stuck in a loop
160 seen.add(child);
161 // find all the frames for this settings page
162 while(!annotations.isEmpty()) {
163 Text annotation = annotations.remove(0);
164 Frame next = annotation.getChild();
165 if(next != null && !seen.contains(next)) {
166 items.addAll(next.getBodyTextItems(false));
167 annotations.addAll(next.getAnnotationItems());
168 seen.add(next);
169 }
170 }
171
172 // parse all the settings items on this page
173 for(Text t : items) {
174 AttributeValuePair avp = new AttributeValuePair(t.getText(), false);
175 try {
176 String settingName = avp.getAttributeOrValue().trim().toLowerCase();
177 // System.out.println(avp.getAttributeOrValue().trim().toLowerCase().replaceAll("^@", ""));
178 Setting s = pd.settings.get(settingName);//.replaceAll("^@", ""));
179 if(s == null) {
180 if(settingName.startsWith("//") || settingName.startsWith("@")) {
181 continue;
182 }
183 // System.out.println("Couldn't find setting \"" + settingName + "\"");
184 List<String> validPages = new LinkedList<String>();
185 // if the setting isn't found on the current page, check all child pages
186 for(String k : _pages.keySet()) {
187 if(k.startsWith(settingsPage) && k.length() > settingsPage.length()) {
188 // System.out.println(k + " is a child of " + settingsPage);
189 PageDescriptor cpd = _pages.get(k);
190 Setting tmp = cpd.settings.get(settingName);
191 if(tmp != null) {
192 // System.out.println("Found setting in subpage: " + k);
193 s = tmp;
194 validPages.add(k);
195 }
196 }
197 }
198
199 if(s == null) {
200 continue;
201 }
202
203 if(validPages.size() > 1) {
204 StringBuffer warnMessage = new StringBuffer("Found multiple matching settings in the following settings subpages: ");
205 String lastPage = "";
206 for(String page : validPages) {
207 warnMessage.append("\"" + page + "\",");
208 lastPage = page;
209 }
210 warnMessage.deleteCharAt(warnMessage.length() - 1);
211 warnMessage.append(" - choosing " + lastPage);
212 MessageBay.warningMessage(warnMessage.toString());
213 }
214 }
215
216 if(s.setSetting(t) && s instanceof VariableSetting) set.add((VariableSetting) s);
217
218 } catch (Exception e) {
219 e.printStackTrace();
220 }
221 }
222
223 // call the onParsed method if one exists
224 if(pd.onParsed != null) {
225 pd.onParsed.invoke(null, text);
226 }
227
228 } catch (Exception e) {
229 e.printStackTrace();
230 return set;
231 }
232
233 // Having parsed this page, we must alter all the items on the frame that they are no longer being shown.
234 // For things such as WidgetCorners, this means that they will be removed from live consideration.
235 Collection<Item> allItems = child.getAllItems();
236 for (Item i: allItems) {
237 i.onParentStateChanged(new ItemParentStateChangedEvent(child, ItemParentStateChangedEvent.EVENT_TYPE_HIDDEN));
238 }
239
240 // if the page was a settings page, check if it has any subpages
241 for(Text t : child.getTextItems()) {
242 set.addAll(parseSettings(t, settingsPage + "."));
243 }
244 return set;
245 }
246
247 public static void generateSettingsTree(Text link) {
248 generateSettingsTree("settings", link);
249 }
250
251 private static void generateSettingsTree(String page, Text text) {
252 Frame parent = text.getParentOrCurrentFrame();
253 FrameCreator frames = new FrameCreator(parent.getFramesetName(), parent.getPath(), page, FrameCreator.ExistingFramesetOptions.AppendSegregatedFrames, false, null);
254 text.setLink(frames.getName());
255
256 // Add subpages of the current page by recursing
257 for (String k: _pages.keySet()) {
258 if (k.startsWith(page.toLowerCase()) && !k.equals(page)) {
259 String name = k.substring(page.length() + 1);
260 if (name.indexOf('.') != -1) {
261 continue;
262 }
263 System.out.println("@Settings: Generating " + name);
264 generateSettingsTree(k, frames.addText(name.substring(0, 1).toUpperCase() + name.substring(1), null, null, null, false));
265 }
266 }
267
268 // Start building current page
269 frames.setLastY(frames.getLastY() + 20);
270 // Add Settings of the current page
271 PageDescriptor pd = _pages.get(page);
272 if (pd == null) {
273 frames.save();
274 return;
275 }
276
277 //Iterator<String> keys = pd.orderedEntries.stream().map(t -> t.toLowerCase()).iterator();
278 Iterator<String> keys = pd.orderedEntries.iterator();
279 while(keys.hasNext()) {
280 String key = keys.next();
281 Setting setting = pd.settings.get(key.toLowerCase());
282 if (setting == null) {
283 continue;
284 }
285
286 // Keep track of were we are placing items on Frames.
287 int x = 0, y = 0;
288
289 Frame currentFrame = frames.getCurrentFrame();
290 if (key.toLowerCase().equals("pass")) {
291 // Special case for Password widgets
292 Text passwordWidgetText = frames.addText("iw: org.expeditee.items.widgets.Passwsord", null, null, null, false);
293 Password pw = new Password(passwordWidgetText, null);
294 pw.setPassword("");
295 currentFrame.removeItem(passwordWidgetText);
296 currentFrame.addAllItems(pw.getItems());
297 x = passwordWidgetText.getX() + passwordWidgetText.getBoundsWidth();
298 y = passwordWidgetText.getY();
299 } else {
300 // Determine the content for a setting label.
301 //String name = key.substring(0, 1).toUpperCase() + key.substring(1);
302 //String name = key;
303
304 // Construct and add text representation for setting.
305 // If a setting has no initialised value then it is not included.
306 String framesetName = currentFrame.getFramesetName();
307 Text template = setting.generateRepresentation(key, framesetName);
308 if (template == null) {
309 continue;
310 }
311 Text settingRepresentation = template.copy();
312 if (settingRepresentation == null || settingRepresentation.getBounds() == null) {
313 continue;
314 }
315 settingRepresentation.setID(currentFrame.getNextItemID());
316 frames.addItem(settingRepresentation, false);
317 x = settingRepresentation.getX() + settingRepresentation.getBoundsWidth();
318 y = settingRepresentation.getY();
319 }
320
321 x = Math.max(250, x + 20);
322 // Add tooltip for setting
323 Text tooltip = currentFrame.addText(x, y, "// " + setting.getTooltip(), null);
324 tooltip.rebuild(true);
325 if (tooltip.getY() + tooltip.getBoundsHeight() > frames.getLastY()) {
326 frames.setLastY(tooltip.getY() + tooltip.getBoundsHeight());
327 }
328 }
329
330 frames.save();
331 }
332}
Note: See TracBrowser for help on using the repository browser.