001: package net.xoetrope.builder.editor;
002:
003: import java.io.BufferedOutputStream;
004: import java.io.FileOutputStream;
005: import java.io.IOException;
006: import java.util.Arrays;
007: import java.util.Collections;
008: import java.util.Comparator;
009: import java.util.Enumeration;
010: import java.util.List;
011:
012: import net.xoetrope.xml.XmlElement;
013: import net.xoetrope.xml.nanoxml.NanoXmlWriter;
014: import net.xoetrope.xui.XProjectManager;
015: import net.xoetrope.xui.style.XStyle;
016: import net.xoetrope.xui.style.XStyleManager;
017: import net.xoetrope.xml.XmlSource;
018: import net.xoetrope.xui.XResourceManager;
019: import java.io.BufferedReader;
020: import net.xoetrope.xui.build.BuildProperties;
021: import net.xoetrope.debug.DebugLogger;
022: import java.awt.Color;
023:
024: /**
025: * A subclass of the XStyleManager intended to allow saving of styles on behalf
026: * of the editor-ide
027: * <p>Copyright (c) Xoetrope Ltd., 1998-2003</p>
028: * @version $Revision: 1.22 $
029: */
030: public class XEditorStyleManager extends XStyleManager {
031: protected XEditorStyleManager(int styleCount) {
032: super (styleCount);
033: }
034:
035: /**
036: * Create the instance. This class now delegates to the project manager.
037: * @deprecated use XEditorProjectManager.getStyleManager() instead
038: */
039: public static XStyleManager getInstance() {
040: return XEditorProjectManager.getStyleManager();
041: }
042:
043: /**
044: * Load the styles from the specified file
045: * @param file the file name of the file to load
046: */
047: public void load(String file) {
048: BufferedReader r = null;
049: try {
050: if (((XEditorProject) XProjectManager.getCurrentProject())
051: .hasProject()) {
052: r = XEditorResourceManager
053: .getBufferedReader(file, null);
054: if (r != null) {
055: XmlElement element = XmlSource.read(r, null);
056:
057: loadXStyle(element, null);
058: baseStyle = getStyle("base");
059: }
060: }
061: } catch (Exception ex) {
062: if (BuildProperties.DEBUG)
063: DebugLogger.trace("Error loading styles file: " + file);
064: ex.printStackTrace();
065: }
066: }
067:
068: /**
069: * Save the styles to the specified file
070: * @param filename
071: */
072: public void saveStyles(String filename) {
073: XmlElement eleStyles = XProjectManager.getXmlParserFactory()
074: .createXmlElement("styles");
075:
076: String[] stylesArray = getStylesArray();
077: addChildStyles(eleStyles, stylesArray, -1);
078: try {
079: FileOutputStream fos = new FileOutputStream(filename);
080: BufferedOutputStream bos = new BufferedOutputStream(fos);
081: NanoXmlWriter writer = new NanoXmlWriter(bos);
082: writer.write(eleStyles, true, 4);
083: bos.close();
084: fos.close();
085: } catch (IOException ex) {
086: ex.printStackTrace();
087: }
088: }
089:
090: /**
091: * Add/derive a refinement of a style
092: * @param eleRoot
093: * @param styleNames
094: * @param start
095: */
096: protected void addChildStyles(XmlElement eleRoot,
097: String[] styleNames, int start) {
098: XmlElement eleNew = null;
099: int i = start;
100: String rootname = "";
101:
102: while (++i < styleNames.length) {
103: String currentStyleName = styleNames[i];
104: int lookup = i == 0 ? 0 : i - 1;
105: String truncName = currentStyleName;
106: if (currentStyleName.indexOf("/") > -1) {
107: truncName = currentStyleName.substring(currentStyleName
108: .lastIndexOf("/") + 1, currentStyleName
109: .length());
110: String parentStyleName = currentStyleName.substring(0,
111: currentStyleName.lastIndexOf("/"));
112: XmlElement eleTemp = addStyle(eleNew, currentStyleName,
113: truncName, getStyle(parentStyleName));
114: String next = "";
115: if ((i + 1) < styleNames.length)
116: next = styleNames[i + 1];
117: if (next.startsWith(currentStyleName)) {
118: String temp = next.substring(currentStyleName
119: .length(), next.length());
120: if (temp.startsWith("/"))
121: eleNew = eleTemp;
122: }
123: } else {
124: eleNew = addStyle(eleRoot, currentStyleName,
125: currentStyleName,
126: getStyleParent(currentStyleName));
127: rootname = currentStyleName;
128: }
129: }
130: }
131:
132: protected XmlElement addStyle(XmlElement eleRoot, String fullName,
133: String newName, XStyle parent) {
134: XmlElement eleNew = eleRoot.createElement("style");
135: eleNew.setAttribute("name", newName);
136: XStyle xstyle = getStyle(fullName);
137: addColorElement(eleNew, xstyle, "color_back",
138: xstyle.COLOR_BACK, parent);
139: addColorElement(eleNew, xstyle, "color_fore",
140: xstyle.COLOR_FORE, parent);
141: addFontStyles(eleNew, xstyle, parent);
142: eleRoot.addChild(eleNew);
143: return eleNew;
144: }
145:
146: /**
147: * Add an element that represents a colour to the style hierarchy
148: * @param ele the source element
149: * @param xstyle the style
150: * @param styleEleName
151: * @param index
152: * @param parent
153: */
154: protected void addColorElement(XmlElement ele, XStyle xstyle,
155: String styleEleName, int index, XStyle parent) {
156: Color color = xstyle.getStyleAsColor(index);
157: Color parentColor = null;
158: if (parent != null)
159: parentColor = parent.getStyleAsColor(index);
160: if (color != null
161: && (parentColor == null || (!color.equals(parentColor)))) {
162: XmlElement eleStyle = ele.createElement(styleEleName);
163: eleStyle.setAttribute("value", formatColor(color.getRed())
164: + formatColor(color.getGreen())
165: + formatColor(color.getBlue()));
166: ele.addChild(eleStyle);
167: }
168: }
169:
170: protected String formatColor(int portion) {
171: String ret = Integer.toHexString(portion);
172: if (ret.length() == 1)
173: ret = "0" + ret;
174: return ret;
175: }
176:
177: protected void addFontStyles(XmlElement ele, XStyle xstyle,
178: XStyle parent) {
179: String fontface = xstyle.getStyleAsString(xstyle.FONT_FACE);
180: String parentFontFace = null;
181: if (parent != null)
182: parentFontFace = parent.getStyleAsString(xstyle.FONT_FACE);
183:
184: if (fontface != null
185: && (parentFontFace == null || (!fontface
186: .equals(parentFontFace)))) {
187: XmlElement eleStyle = ele.createElement("font_face");
188: eleStyle.setAttribute("value", fontface);
189: ele.addChild(eleStyle);
190: }
191:
192: addIntElement(ele, xstyle, "font_size", xstyle.FONT_SIZE,
193: parent);
194: addIntElement(ele, xstyle, "font_weight", xstyle.FONT_WEIGHT,
195: parent);
196: addIntElement(ele, xstyle, "font_italic", xstyle.FONT_ITALIC,
197: parent);
198: }
199:
200: protected void addIntElement(XmlElement ele, XStyle xstyle,
201: String styleEleName, int index, XStyle parent) {
202: int prop = xstyle.getStyleAsInt(index);
203: int parentProp = -1;
204: if (parent != null)
205: parentProp = parent.getStyleAsInt(index);
206: if (prop != parentProp) {
207: XmlElement eleStyle = ele.createElement(styleEleName);
208: eleStyle.setAttribute("value", String.valueOf(prop));
209: ele.addChild(eleStyle);
210: }
211: }
212:
213: private String[] sortItems(String data[]) {
214: List list = Arrays.asList(data);
215: Collections.sort(list, new CaseInsensitiveComparator());
216: return (String[]) list.toArray();
217: }
218:
219: private static class CaseInsensitiveComparator implements
220: Comparator {
221: public int compare(Object element1, Object element2) {
222: String lower1 = element1.toString().toLowerCase();
223: String lower2 = element2.toString().toLowerCase();
224: return lower1.compareTo(lower2);
225: }
226: }
227:
228: /**
229: * Get an array of style names
230: * @return
231: */
232: public String[] getStylesArray() {
233: String ret[];
234:
235: ret = new String[styles.size()];
236: Enumeration e = styles.keys();
237: int count = 0;
238: while (e.hasMoreElements()) {
239: String temp = (String) e.nextElement();
240: ret[count] = temp;
241: count++;
242: }
243: ret = sortItems(ret);
244: return ret;
245: }
246:
247: public void removeStyle(String name) {
248: styles.remove(name);
249: }
250:
251: public void removeAll() {
252: styles.clear();
253: mergedStyles.clear();
254: fontCache.clear();
255: }
256: }
|