6298488bc935ab25fd003cc896619d8c119782c5
[old-projects.git] / ekit / com / hexidec / ekit / component / HTMLUtilities.java
1 /*
2 GNU Lesser General Public License
3
4 HTMLUtilities - Special Utility Functions For Ekit
5 Copyright (C) 2003 Rafael Cieplinski, modified by Howard Kistler
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 package com.hexidec.ekit.component;
23
24 import java.io.*;
25 import java.lang.reflect.*;
26 import java.util.*;
27 import javax.swing.*;
28 import javax.swing.text.*;
29 import javax.swing.text.html.*;
30
31 import com.hexidec.ekit.EkitCore;
32 import com.hexidec.ekit.component.*;
33
34 public 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 JTextPane 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
492 }