001: /*
002: GNU Lesser General Public License
003:
004: HTMLUtilities - Special Utility Functions For Ekit
005: Copyright (C) 2003 Rafael Cieplinski & Howard Kistler
006:
007: This library is free software; you can redistribute it and/or
008: modify it under the terms of the GNU Lesser General Public
009: License as published by the Free Software Foundation; either
010: version 2.1 of the License, or (at your option) any later version.
011:
012: This library is distributed in the hope that it will be useful,
013: but WITHOUT ANY WARRANTY; without even the implied warranty of
014: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: Lesser General Public License for more details.
016:
017: You should have received a copy of the GNU Lesser General Public
018: License along with this library; if not, write to the Free Software
019: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package org.objectweb.salome_tmf.ihm.main.htmleditor.component;
022:
023: import java.io.IOException;
024: import java.util.Enumeration;
025: import java.util.Hashtable;
026:
027: import javax.swing.JTextArea;
028: import javax.swing.JTextPane;
029: import javax.swing.text.BadLocationException;
030: import javax.swing.text.Element;
031: import javax.swing.text.SimpleAttributeSet;
032: import javax.swing.text.html.HTML;
033:
034: import org.objectweb.salome_tmf.ihm.main.htmleditor.EkitCore;
035:
036: public class HTMLUtilities {
037: EkitCore parent;
038: Hashtable tags = new Hashtable();
039:
040: public HTMLUtilities(EkitCore newParent) {
041: parent = newParent;
042: HTML.Tag[] tagList = HTML.getAllTags();
043: for (int i = 0; i < tagList.length; i++) {
044: tags.put(tagList[i].toString(), tagList[i]);
045: }
046: /*
047: HTML.Tag classTag = new HTML.Tag();
048: Field[] fields = classTag.getClass().getDeclaredFields();
049: for(int i = 0; i < fields.length; i++)
050: {
051: try
052: {
053: System.out.println("Adding " + (String)fields[i].get(null).toString() + " => " + (HTML.Tag)fields[i].get(null));
054: tags.put((String)fields[i].get(null).toString(), (HTML.Tag)fields[i].get(null));
055: }
056: catch (IllegalAccessException iae)
057: {
058: }
059: }
060: */
061: }
062:
063: /** Diese Methode fügt durch String-Manipulation in jtpSource
064: * ein neues Listenelement hinzu, content ist dabei der Text der in dem neuen
065: * Element stehen soll
066: */
067: public void insertListElement(String content) {
068: int pos = parent.getCaretPosition();
069: String source = parent.getSourcePane().getText();
070: boolean hit = false;
071: String idString;
072: int counter = 0;
073: do {
074: hit = false;
075: idString = "diesisteineidzumsuchenimsource" + counter;
076: if (source.indexOf(idString) > -1) {
077: counter++;
078: hit = true;
079: if (counter > 10000) {
080: return;
081: }
082: }
083: } while (hit);
084: Element element = getListItemParent();
085: if (element == null) {
086: return;
087: }
088: SimpleAttributeSet sa = new SimpleAttributeSet(element
089: .getAttributes());
090: sa.addAttribute("id", idString);
091: parent.getExtendedHtmlDoc().replaceAttributes(element, sa,
092: HTML.Tag.LI);
093: parent.refreshOnUpdate();
094: source = parent.getSourcePane().getText();
095: StringBuffer newHtmlString = new StringBuffer();
096: int[] positions = getPositions(element, source, true, idString);
097: newHtmlString.append(source.substring(0, positions[3]));
098: newHtmlString.append("<li>");
099: newHtmlString.append(content);
100: newHtmlString.append("</li>");
101: newHtmlString.append(source.substring(positions[3] + 1, source
102: .length()));
103: parent.getTextPane().setText(newHtmlString.toString());
104: parent.refreshOnUpdate();
105: parent.setCaretPosition(pos - 1);
106: element = getListItemParent();
107: sa = new SimpleAttributeSet(element.getAttributes());
108: sa = removeAttributeByKey(sa, "id");
109: parent.getExtendedHtmlDoc().replaceAttributes(element, sa,
110: HTML.Tag.LI);
111: }
112:
113: /** Diese Methode löscht durch Stringmanipulation in jtpSource das übergebene Element,
114: * Alternative für removeElement in ExtendedHTMLDocument, mit closingTag wird angegeben
115: * ob es ein schließenden Tag gibt
116: */
117: public void removeTag(Element element, boolean closingTag) {
118: if (element == null) {
119: return;
120: }
121: int pos = parent.getCaretPosition();
122: HTML.Tag tag = getHTMLTag(element);
123: // Versieht den Tag mit einer einmaligen ID
124: String source = parent.getSourcePane().getText();
125: boolean hit = false;
126: String idString;
127: int counter = 0;
128: do {
129: hit = false;
130: idString = "diesisteineidzumsuchenimsource" + counter;
131: if (source.indexOf(idString) > -1) {
132: counter++;
133: hit = true;
134: if (counter > 10000) {
135: return;
136: }
137: }
138: } while (hit);
139: SimpleAttributeSet sa = new SimpleAttributeSet(element
140: .getAttributes());
141: sa.addAttribute("id", idString);
142: parent.getExtendedHtmlDoc().replaceAttributes(element, sa, tag);
143: parent.refreshOnUpdate();
144: source = parent.getSourcePane().getText();
145: StringBuffer newHtmlString = new StringBuffer();
146: int[] position = getPositions(element, source, closingTag,
147: idString);
148: if (position == null) {
149: return;
150: }
151: for (int i = 0; i < position.length; i++) {
152: if (position[i] < 0) {
153: return;
154: }
155: }
156: int beginStartTag = position[0];
157: int endStartTag = position[1];
158: if (closingTag) {
159: int beginEndTag = position[2];
160: int endEndTag = position[3];
161: newHtmlString.append(source.substring(0, beginStartTag));
162: newHtmlString.append(source.substring(endStartTag,
163: beginEndTag));
164: newHtmlString.append(source.substring(endEndTag, source
165: .length()));
166: } else {
167: newHtmlString.append(source.substring(0, beginStartTag));
168: newHtmlString.append(source.substring(endStartTag, source
169: .length()));
170: }
171: parent.getTextPane().setText(newHtmlString.toString());
172: parent.refreshOnUpdate();
173: }
174:
175: /** Diese Methode gibt jeweils den Start- und Endoffset des Elements
176: * sowie dem entsprechenden schließenden Tag zurück
177: */
178: private int[] getPositions(Element element, String source,
179: boolean closingTag, String idString) {
180: HTML.Tag tag = getHTMLTag(element);
181: int[] position = new int[4];
182: for (int i = 0; i < position.length; i++) {
183: position[i] = -1;
184: }
185: String searchString = "<" + tag.toString();
186: int caret = -1; // aktuelle Position im sourceString
187: if ((caret = source.indexOf(idString)) != -1) {
188: position[0] = source.lastIndexOf("<", caret);
189: position[1] = source.indexOf(">", caret) + 1;
190: }
191: if (closingTag) {
192: String searchEndTagString = "</" + tag.toString() + ">";
193: int hitUp = 0;
194: int beginEndTag = -1;
195: int endEndTag = -1;
196: caret = position[1];
197: boolean end = false;
198: // Position des 1. Treffer auf den End-Tag wird bestimmt
199: beginEndTag = source.indexOf(searchEndTagString, caret);
200: endEndTag = beginEndTag + searchEndTagString.length();
201: // Schleife läuft solange, bis keine neuen StartTags mehr gefunden werden
202: int interncaret = position[1];
203: do {
204: int temphitpoint = -1;
205: boolean flaghitup = false;
206: // Schleife sucht zwischen dem Start- und End-Tag nach neuen Start-Tags
207: hitUp = 0;
208: do {
209: flaghitup = false;
210: temphitpoint = source.indexOf(searchString,
211: interncaret);
212: if (temphitpoint > 0 && temphitpoint < beginEndTag) {
213: hitUp++;
214: flaghitup = true;
215: interncaret = temphitpoint
216: + searchString.length();
217: }
218: } while (flaghitup);
219: // hitUp enthält die Anzahl der neuen Start-Tags
220: if (hitUp == 0) {
221: end = true;
222: } else {
223: for (int i = 1; i <= hitUp; i++) {
224: caret = endEndTag;
225: beginEndTag = source.indexOf(
226: searchEndTagString, caret);
227: endEndTag = beginEndTag
228: + searchEndTagString.length();
229: }
230: end = false;
231: }
232: } while (!end);
233: if (beginEndTag < 0 | endEndTag < 0) {
234: return null;
235: }
236: position[2] = beginEndTag;
237: position[3] = endEndTag;
238: }
239: return position;
240: }
241:
242: /* Diese Methode prüft ob der übergebene Tag sich in der Hierachie nach oben befindet */
243: public boolean checkParentsTag(HTML.Tag tag) {
244: Element e = parent.getExtendedHtmlDoc().getParagraphElement(
245: parent.getCaretPosition());
246: String tagString = tag.toString();
247: if (e.getName().equalsIgnoreCase(tag.toString())) {
248: return true;
249: }
250: do {
251: if ((e = e.getParentElement()).getName().equalsIgnoreCase(
252: tagString)) {
253: return true;
254: }
255: } while (!(e.getName().equalsIgnoreCase("html")));
256: return false;
257: }
258:
259: /* Diese Methoden geben das erste gefundende dem übergebenen tags entsprechende Element zurück */
260: public Element getListItemParent() {
261: String listItemTag = HTML.Tag.LI.toString();
262: Element eleSearch = parent.getExtendedHtmlDoc()
263: .getCharacterElement(parent.getCaretPosition());
264: do {
265: if (listItemTag.equals(eleSearch.getName())) {
266: return eleSearch;
267: }
268: eleSearch = eleSearch.getParentElement();
269: } while (eleSearch.getName() != HTML.Tag.HTML.toString());
270: return null;
271: }
272:
273: /* Diese Methoden entfernen Attribute aus dem SimpleAttributeSet, gemäß den übergebenen Werten, und
274: geben das Ergebnis als SimpleAttributeSet zurück*/
275: public SimpleAttributeSet removeAttributeByKey(
276: SimpleAttributeSet sourceAS, String removeKey) {
277: SimpleAttributeSet temp = new SimpleAttributeSet();
278: temp.addAttribute(removeKey, "NULL");
279: return removeAttribute(sourceAS, temp);
280: }
281:
282: public SimpleAttributeSet removeAttribute(
283: SimpleAttributeSet sourceAS, SimpleAttributeSet removeAS) {
284: try {
285: String[] sourceKeys = new String[sourceAS
286: .getAttributeCount()];
287: String[] sourceValues = new String[sourceAS
288: .getAttributeCount()];
289: Enumeration sourceEn = sourceAS.getAttributeNames();
290: int i = 0;
291: while (sourceEn.hasMoreElements()) {
292: Object temp = new Object();
293: temp = sourceEn.nextElement();
294: sourceKeys[i] = (String) temp.toString();
295: sourceValues[i] = new String();
296: sourceValues[i] = (String) sourceAS.getAttribute(temp)
297: .toString();
298: i++;
299: }
300: String[] removeKeys = new String[removeAS
301: .getAttributeCount()];
302: String[] removeValues = new String[removeAS
303: .getAttributeCount()];
304: Enumeration removeEn = removeAS.getAttributeNames();
305: int j = 0;
306: while (removeEn.hasMoreElements()) {
307: removeKeys[j] = (String) removeEn.nextElement()
308: .toString();
309: removeValues[j] = (String) removeAS.getAttribute(
310: removeKeys[j]).toString();
311: j++;
312: }
313: SimpleAttributeSet result = new SimpleAttributeSet();
314: boolean hit = false;
315: for (int countSource = 0; countSource < sourceKeys.length; countSource++) {
316: hit = false;
317: if (sourceKeys[countSource] == "name"
318: | sourceKeys[countSource] == "resolver") {
319: hit = true;
320: } else {
321: for (int countRemove = 0; countRemove < removeKeys.length; countRemove++) {
322: if (removeKeys[countRemove] != "NULL") {
323: if (sourceKeys[countSource].toString() == removeKeys[countRemove]
324: .toString()) {
325: if (removeValues[countRemove] != "NULL") {
326: if (sourceValues[countSource]
327: .toString() == removeValues[countRemove]
328: .toString()) {
329: hit = true;
330: }
331: } else if (removeValues[countRemove] == "NULL") {
332: hit = true;
333: }
334: }
335: } else if (removeKeys[countRemove] == "NULL") {
336: if (sourceValues[countSource].toString() == removeValues[countRemove]
337: .toString()) {
338: hit = true;
339: }
340: }
341: }
342: }
343: if (!hit) {
344: result.addAttribute(sourceKeys[countSource]
345: .toString(), sourceValues[countSource]
346: .toString());
347: }
348: }
349: return result;
350: } catch (ClassCastException cce) {
351: return null;
352: }
353: }
354:
355: /* liefert den entsprechenden HTML.Tag zum Element zurück */
356: public HTML.Tag getHTMLTag(Element e) {
357: if (tags.containsKey(e.getName())) {
358: return (HTML.Tag) tags.get(e.getName());
359: } else {
360: return null;
361: }
362: }
363:
364: public String[] getUniString(int strings) {
365: parent.refreshOnUpdate();
366: String[] result = new String[strings];
367: String source = parent.getSourcePane().getText();
368: for (int i = 0; i < strings; i++) {
369: int start = -1, end = -1;
370: boolean hit = false;
371: String idString;
372: int counter = 0;
373: do {
374: hit = false;
375: idString = "diesisteineidzumsuchen" + counter + "#" + i;
376: if (source.indexOf(idString) > -1) {
377: counter++;
378: hit = true;
379: if (counter > 10000) {
380: return null;
381: }
382: }
383: } while (hit);
384: result[i] = idString;
385: }
386: return result;
387: }
388:
389: public void delete() throws BadLocationException, IOException {
390: JTextPane jtpMain = parent.getTextPane();
391: JTextArea jtpSource = parent.getSourcePane();
392: ExtendedHTMLDocument htmlDoc = parent.getExtendedHtmlDoc();
393: int selStart = jtpMain.getSelectionStart();
394: int selEnd = jtpMain.getSelectionEnd();
395: String[] posStrings = getUniString(2);
396: if (posStrings == null) {
397: return;
398: }
399: htmlDoc.insertString(selStart, posStrings[0], null);
400: htmlDoc.insertString(selEnd + posStrings[0].length(),
401: posStrings[1], null);
402: parent.refreshOnUpdate();
403: int start = jtpSource.getText().indexOf(posStrings[0]);
404: int end = jtpSource.getText().indexOf(posStrings[1]);
405: if (start == -1 || end == -1) {
406: return;
407: }
408: String htmlString = new String();
409: htmlString += jtpSource.getText().substring(0, start);
410: htmlString += jtpSource.getText().substring(
411: start + posStrings[0].length(), end);
412: htmlString += jtpSource.getText().substring(
413: end + posStrings[1].length(),
414: jtpSource.getText().length());
415: String source = htmlString;
416: end = end - posStrings[0].length();
417: htmlString = new String();
418: htmlString += source.substring(0, start);
419: htmlString += getAllTableTags(source.substring(start, end));
420: htmlString += source.substring(end, source.length());
421: parent.getTextPane().setText(htmlString);
422: parent.refreshOnUpdate();
423: }
424:
425: private String getAllTableTags(String source)
426: throws BadLocationException, IOException {
427: StringBuffer result = new StringBuffer();
428: int caret = -1;
429: do {
430: caret++;
431: int[] tableCarets = new int[6];
432: tableCarets[0] = source.indexOf("<table", caret);
433: tableCarets[1] = source.indexOf("<tr", caret);
434: tableCarets[2] = source.indexOf("<td", caret);
435: tableCarets[3] = source.indexOf("</table", caret);
436: tableCarets[4] = source.indexOf("</tr", caret);
437: tableCarets[5] = source.indexOf("</td", caret);
438: java.util.Arrays.sort(tableCarets);
439: caret = -1;
440: for (int i = 0; i < tableCarets.length; i++) {
441: if (tableCarets[i] >= 0) {
442: caret = tableCarets[i];
443: break;
444: }
445: }
446: if (caret != -1) {
447: result.append(source.substring(caret, source.indexOf(
448: ">", caret) + 1));
449: }
450: } while (caret != -1);
451: return result.toString();
452: }
453:
454: }
|