Import of Ekit 0.9h
[old-projects.git] / ekit / com / hexidec / ekit / component / HTMLUtilities.java
CommitLineData
6ce136da
JL
1/*
2GNU Lesser General Public License
3
4HTMLUtilities - Special Utility Functions For Ekit
5Copyright (C) 2003 Rafael Cieplinski & Howard Kistler
6
7This library is free software; you can redistribute it and/or
8modify it under the terms of the GNU Lesser General Public
9License as published by the Free Software Foundation; either
10version 2.1 of the License, or (at your option) any later version.
11
12This library is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public
18License along with this library; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20*/
21
22package com.hexidec.ekit.component;
23
24import java.io.*;
25import java.lang.reflect.*;
26import java.util.*;
27import javax.swing.*;
28import javax.swing.text.*;
29import javax.swing.text.html.*;
30
31import com.hexidec.ekit.EkitCore;
32import com.hexidec.ekit.component.*;
33
34public class HTMLUtilities
35{
36 EkitCore parent;
37 Hashtable tags = new Hashtable();
38
39 public HTMLUtilities(EkitCore newParent)
40 {
41 parent = newParent;
42 HTML.Tag[] tagList = HTML.getAllTags();
43 for(int i = 0; i < tagList.length; i++)
44 {
45 tags.put(tagList[i].toString(), tagList[i]);
46 }
47/*
48 HTML.Tag classTag = new HTML.Tag();
49 Field[] fields = classTag.getClass().getDeclaredFields();
50 for(int i = 0; i < fields.length; i++)
51 {
52 try
53 {
54 System.out.println("Adding " + (String)fields[i].get(null).toString() + " => " + (HTML.Tag)fields[i].get(null));
55 tags.put((String)fields[i].get(null).toString(), (HTML.Tag)fields[i].get(null));
56 }
57 catch (IllegalAccessException iae)
58 {
59 }
60 }
61*/
62 }
63
64 /** Diese Methode fügt durch String-Manipulation in jtpSource
65 * ein neues Listenelement hinzu, content ist dabei der Text der in dem neuen
66 * Element stehen soll
67 */
68 public void insertListElement(String content)
69 {
70 int pos = parent.getCaretPosition();
71 String source = parent.getSourcePane().getText();
72 boolean hit = false;
73 String idString;
74 int counter = 0;
75 do
76 {
77 hit = false;
78 idString = "diesisteineidzumsuchenimsource" + counter;
79 if(source.indexOf(idString) > -1)
80 {
81 counter++;
82 hit = true;
83 if(counter > 10000)
84 {
85 return;
86 }
87 }
88 } while(hit);
89 Element element = getListItemParent();
90 if(element == null)
91 {
92 return;
93 }
94 SimpleAttributeSet sa = new SimpleAttributeSet(element.getAttributes());
95 sa.addAttribute("id", idString);
96 parent.getExtendedHtmlDoc().replaceAttributes(element, sa, HTML.Tag.LI);
97 parent.refreshOnUpdate();
98 source = parent.getSourcePane().getText();
99 StringBuffer newHtmlString = new StringBuffer();
100 int[] positions = getPositions(element, source, true, idString);
101 newHtmlString.append(source.substring(0, positions[3]));
102 newHtmlString.append("<li>");
103 newHtmlString.append(content);
104 newHtmlString.append("</li>");
105 newHtmlString.append(source.substring(positions[3] + 1, source.length()));
106 parent.getTextPane().setText(newHtmlString.toString());
107 parent.refreshOnUpdate();
108 parent.setCaretPosition(pos - 1);
109 element = getListItemParent();
110 sa = new SimpleAttributeSet(element.getAttributes());
111 sa = removeAttributeByKey(sa, "id");
112 parent.getExtendedHtmlDoc().replaceAttributes(element, sa, HTML.Tag.LI);
113 }
114
115 /** Diese Methode löscht durch Stringmanipulation in jtpSource das übergebene Element,
116 * Alternative für removeElement in ExtendedHTMLDocument, mit closingTag wird angegeben
117 * ob es ein schließenden Tag gibt
118 */
119 public void removeTag(Element element, boolean closingTag)
120 {
121 if(element == null)
122 {
123 return;
124 }
125 int pos = parent.getCaretPosition();
126 HTML.Tag tag = getHTMLTag(element);
127 // Versieht den Tag mit einer einmaligen ID
128 String source = parent.getSourcePane().getText();
129 boolean hit = false;
130 String idString;
131 int counter = 0;
132 do
133 {
134 hit = false;
135 idString = "diesisteineidzumsuchenimsource" + counter;
136 if(source.indexOf(idString) > -1)
137 {
138 counter++;
139 hit = true;
140 if(counter > 10000)
141 {
142 return;
143 }
144 }
145 } while(hit);
146 SimpleAttributeSet sa = new SimpleAttributeSet(element.getAttributes());
147 sa.addAttribute("id", idString);
148 parent.getExtendedHtmlDoc().replaceAttributes(element, sa, tag);
149 parent.refreshOnUpdate();
150 source = parent.getSourcePane().getText();
151 StringBuffer newHtmlString = new StringBuffer();
152 int[] position = getPositions(element, source, closingTag, idString);
153 if(position == null)
154 {
155 return;
156 }
157 for(int i = 0; i < position.length; i++)
158 {
159 if(position[i] < 0)
160 {
161 return;
162 }
163 }
164 int beginStartTag = position[0];
165 int endStartTag = position[1];
166 if(closingTag)
167 {
168 int beginEndTag = position[2];
169 int endEndTag = position[3];
170 newHtmlString.append(source.substring(0, beginStartTag));
171 newHtmlString.append(source.substring(endStartTag, beginEndTag));
172 newHtmlString.append(source.substring(endEndTag, source.length()));
173 }
174 else
175 {
176 newHtmlString.append(source.substring(0, beginStartTag));
177 newHtmlString.append(source.substring(endStartTag, source.length()));
178 }
179 parent.getTextPane().setText(newHtmlString.toString());
180 parent.refreshOnUpdate();
181 }
182
183 /** Diese Methode gibt jeweils den Start- und Endoffset des Elements
184 * sowie dem entsprechenden schließenden Tag zurück
185 */
186 private int[] getPositions(Element element, String source, boolean closingTag, String idString)
187 {
188 HTML.Tag tag = getHTMLTag(element);
189 int[] position = new int[4];
190 for(int i = 0; i < position.length; i++)
191 {
192 position[i] = -1;
193 }
194 String searchString = "<" + tag.toString();
195 int caret = -1; // aktuelle Position im sourceString
196 if((caret = source.indexOf(idString)) != -1)
197 {
198 position[0] = source.lastIndexOf("<",caret);
199 position[1] = source.indexOf(">",caret)+1;
200 }
201 if(closingTag)
202 {
203 String searchEndTagString = "</" + tag.toString() + ">";
204 int hitUp = 0;
205 int beginEndTag = -1;
206 int endEndTag = -1;
207 caret = position[1];
208 boolean end = false;
209 // Position des 1. Treffer auf den End-Tag wird bestimmt
210 beginEndTag = source.indexOf(searchEndTagString, caret);
211 endEndTag = beginEndTag + searchEndTagString.length();
212 // Schleife läuft solange, bis keine neuen StartTags mehr gefunden werden
213 int interncaret = position[1];
214 do
215 {
216 int temphitpoint = -1;
217 boolean flaghitup = false;
218 // Schleife sucht zwischen dem Start- und End-Tag nach neuen Start-Tags
219 hitUp = 0;
220 do
221 {
222 flaghitup = false;
223 temphitpoint = source.indexOf(searchString, interncaret);
224 if(temphitpoint > 0 && temphitpoint < beginEndTag)
225 {
226 hitUp++;
227 flaghitup = true;
228 interncaret = temphitpoint + searchString.length();
229 }
230 } while(flaghitup);
231 // hitUp enthält die Anzahl der neuen Start-Tags
232 if(hitUp == 0)
233 {
234 end = true;
235 }
236 else
237 {
238 for(int i = 1; i <= hitUp; i++)
239 {
240 caret = endEndTag;
241 beginEndTag = source.indexOf(searchEndTagString, caret);
242 endEndTag = beginEndTag + searchEndTagString.length();
243 }
244 end = false;
245 }
246 } while(!end);
247 if(beginEndTag < 0 | endEndTag < 0)
248 {
249 return null;
250 }
251 position[2] = beginEndTag;
252 position[3] = endEndTag;
253 }
254 return position;
255 }
256
257 /* Diese Methode prüft ob der übergebene Tag sich in der Hierachie nach oben befindet */
258 public boolean checkParentsTag(HTML.Tag tag)
259 {
260 Element e = parent.getExtendedHtmlDoc().getParagraphElement(parent.getCaretPosition());
261 String tagString = tag.toString();
262 if(e.getName().equalsIgnoreCase(tag.toString()))
263 {
264 return true;
265 }
266 do
267 {
268 if((e = e.getParentElement()).getName().equalsIgnoreCase(tagString))
269 {
270 return true;
271 }
272 } while(!(e.getName().equalsIgnoreCase("html")));
273 return false;
274 }
275
276 /* Diese Methoden geben das erste gefundende dem übergebenen tags entsprechende Element zurück */
277 public Element getListItemParent()
278 {
279 String listItemTag = HTML.Tag.LI.toString();
280 Element eleSearch = parent.getExtendedHtmlDoc().getCharacterElement(parent.getCaretPosition());
281 do
282 {
283 if(listItemTag.equals(eleSearch.getName()))
284 {
285 return eleSearch;
286 }
287 eleSearch = eleSearch.getParentElement();
288 } while(eleSearch.getName() != HTML.Tag.HTML.toString());
289 return null;
290 }
291
292 /* Diese Methoden entfernen Attribute aus dem SimpleAttributeSet, gemäß den übergebenen Werten, und
293 geben das Ergebnis als SimpleAttributeSet zurück*/
294 public SimpleAttributeSet removeAttributeByKey(SimpleAttributeSet sourceAS, String removeKey)
295 {
296 SimpleAttributeSet temp = new SimpleAttributeSet();
297 temp.addAttribute(removeKey, "NULL");
298 return removeAttribute(sourceAS, temp);
299 }
300
301 public SimpleAttributeSet removeAttribute(SimpleAttributeSet sourceAS, SimpleAttributeSet removeAS)
302 {
303 try
304 {
305 String[] sourceKeys = new String[sourceAS.getAttributeCount()];
306 String[] sourceValues = new String[sourceAS.getAttributeCount()];
307 Enumeration sourceEn = sourceAS.getAttributeNames();
308 int i = 0;
309 while(sourceEn.hasMoreElements())
310 {
311 Object temp = new Object();
312 temp = sourceEn.nextElement();
313 sourceKeys[i] = (String) temp.toString();
314 sourceValues[i] = new String();
315 sourceValues[i] = (String) sourceAS.getAttribute(temp).toString();
316 i++;
317 }
318 String[] removeKeys = new String[removeAS.getAttributeCount()];
319 String[] removeValues = new String[removeAS.getAttributeCount()];
320 Enumeration removeEn = removeAS.getAttributeNames();
321 int j = 0;
322 while(removeEn.hasMoreElements())
323 {
324 removeKeys[j] = (String) removeEn.nextElement().toString();
325 removeValues[j] = (String) removeAS.getAttribute(removeKeys[j]).toString();
326 j++;
327 }
328 SimpleAttributeSet result = new SimpleAttributeSet();
329 boolean hit = false;
330 for(int countSource = 0; countSource < sourceKeys.length; countSource++)
331 {
332 hit = false;
333 if(sourceKeys[countSource] == "name" | sourceKeys[countSource] == "resolver")
334 {
335 hit = true;
336 }
337 else
338 {
339 for(int countRemove = 0; countRemove < removeKeys.length; countRemove++)
340 {
341 if(removeKeys[countRemove] != "NULL")
342 {
343 if(sourceKeys[countSource].toString() == removeKeys[countRemove].toString())
344 {
345 if(removeValues[countRemove] != "NULL")
346 {
347 if(sourceValues[countSource].toString() == removeValues[countRemove].toString())
348 {
349 hit = true;
350 }
351 }
352 else if(removeValues[countRemove] == "NULL")
353 {
354 hit = true;
355 }
356 }
357 }
358 else if(removeKeys[countRemove] == "NULL")
359 {
360 if(sourceValues[countSource].toString() == removeValues[countRemove].toString())
361 {
362 hit = true;
363 }
364 }
365 }
366 }
367 if(!hit)
368 {
369 result.addAttribute(sourceKeys[countSource].toString(), sourceValues[countSource].toString());
370 }
371 }
372 return result;
373 }
374 catch (ClassCastException cce)
375 {
376 return null;
377 }
378 }
379
380 /* liefert den entsprechenden HTML.Tag zum Element zurück */
381 public HTML.Tag getHTMLTag(Element e)
382 {
383 if(tags.containsKey(e.getName()))
384 {
385 return (HTML.Tag)tags.get(e.getName());
386 }
387 else
388 {
389 return null;
390 }
391 }
392
393 public String[] getUniString(int strings)
394 {
395 parent.refreshOnUpdate();
396 String[] result = new String[strings];
397 String source = parent.getSourcePane().getText();
398 for(int i=0; i<strings; i++)
399 {
400 int start = -1, end = -1;
401 boolean hit = false;
402 String idString;
403 int counter = 0;
404 do
405 {
406 hit = false;
407 idString = "diesisteineidzumsuchen" + counter + "#" + i;
408 if(source.indexOf(idString) > -1)
409 {
410 counter++;
411 hit = true;
412 if(counter > 10000)
413 {
414 return null;
415 }
416 }
417 } while(hit);
418 result[i] = idString;
419 }
420 return result;
421 }
422
423 public void delete()
424 throws BadLocationException,IOException
425 {
426 JTextPane jtpMain = parent.getTextPane();
427 JTextArea jtpSource = parent.getSourcePane();
428 ExtendedHTMLDocument htmlDoc = parent.getExtendedHtmlDoc();
429 int selStart = jtpMain.getSelectionStart();
430 int selEnd = jtpMain.getSelectionEnd();
431 String[] posStrings = getUniString(2);
432 if(posStrings == null)
433 {
434 return;
435 }
436 htmlDoc.insertString(selStart,posStrings[0],null);
437 htmlDoc.insertString(selEnd+posStrings[0].length(),posStrings[1],null);
438 parent.refreshOnUpdate();
439 int start = jtpSource.getText().indexOf(posStrings[0]);
440 int end = jtpSource.getText().indexOf(posStrings[1]);
441 if(start == -1 || end == -1)
442 {
443 return;
444 }
445 String htmlString = new String();
446 htmlString += jtpSource.getText().substring(0,start);
447 htmlString += jtpSource.getText().substring(start + posStrings[0].length(), end);
448 htmlString += jtpSource.getText().substring(end + posStrings[1].length(), jtpSource.getText().length());
449 String source = htmlString;
450 end = end - posStrings[0].length();
451 htmlString = new String();
452 htmlString += source.substring(0,start);
453 htmlString += getAllTableTags(source.substring(start, end));
454 htmlString += source.substring(end, source.length());
455 parent.getTextPane().setText(htmlString);
456 parent.refreshOnUpdate();
457 }
458
459 private String getAllTableTags(String source)
460 throws BadLocationException,IOException
461 {
462 StringBuffer result = new StringBuffer();
463 int caret = -1;
464 do
465 {
466 caret++;
467 int[] tableCarets = new int[6];
468 tableCarets[0] = source.indexOf("<table",caret);
469 tableCarets[1] = source.indexOf("<tr",caret);
470 tableCarets[2] = source.indexOf("<td",caret);
471 tableCarets[3] = source.indexOf("</table",caret);
472 tableCarets[4] = source.indexOf("</tr",caret);
473 tableCarets[5] = source.indexOf("</td",caret);
474 java.util.Arrays.sort(tableCarets);
475 caret = -1;
476 for(int i=0; i<tableCarets.length; i++)
477 {
478 if(tableCarets[i] >= 0)
479 {
480 caret = tableCarets[i];
481 break;
482 }
483 }
484 if(caret != -1)
485 {
486 result.append(source.substring(caret,source.indexOf(">",caret)+1));
487 }
488 } while(caret != -1);
489 return result.toString();
490 }
491
c2da4d40 492}