PageRenderTime 247ms CodeModel.GetById 199ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre5/org/gjt/sp/jedit/textarea/FoldVisibilityManager.java

#
Java | 904 lines | 604 code | 113 blank | 187 comment | 167 complexity | 874bedbae18c01f1a89f529ac7dcf688 MD5 | raw file
  1/*
  2 * FoldVisibilityManager.java - Controls fold visiblity
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2001, 2002 Slava Pestov
  7 *
  8 * This program is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU General Public License
 10 * as published by the Free Software Foundation; either version 2
 11 * of the License, or any later version.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; if not, write to the Free Software
 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 21 */
 22
 23package org.gjt.sp.jedit.textarea;
 24
 25//{{{ Imports
 26import java.awt.Toolkit;
 27import org.gjt.sp.jedit.buffer.OffsetManager;
 28import org.gjt.sp.jedit.*;
 29//}}}
 30
 31/**
 32 * Manages fold visibility.
 33 *
 34 * This class defines methods for translating between physical and virtual
 35 * line numbers, for determining which lines are visible and which aren't,
 36 * and for expanding and collapsing folds.<p>
 37 *
 38 * Note that a "physical" line number is a line index, numbered from the
 39 * start of the buffer. A "virtual" line number is a visible line index;
 40 * lines after a collapsed fold have a virtual line number that is less
 41 * than their physical line number, for example.<p>
 42 *
 43 * You can use the <code>physicalToVirtual()</code> and
 44 * <code>virtualToPhysical()</code> methods to convert one type of line
 45 * number to another.
 46 *
 47 * @author Slava Pestov
 48 * @version $Id: FoldVisibilityManager.java 3987 2002-01-21 11:36:47Z spestov $
 49 * @since jEdit 4.0pre1
 50 */
 51public class FoldVisibilityManager
 52{
 53	//{{{ FoldVisibilityManager constructor
 54	public FoldVisibilityManager(Buffer buffer, OffsetManager offsetMgr,
 55		JEditTextArea textArea)
 56	{
 57		this.buffer = buffer;
 58		this.offsetMgr = offsetMgr;
 59		this.textArea = textArea;
 60	} //}}}
 61
 62	//{{{ isNarrowed() method
 63	/**
 64	 * Returns if the buffer has been narrowed.
 65	 * @since jEdit 4.0pre2
 66	 */
 67	public boolean isNarrowed()
 68	{
 69		return narrowed;
 70	} //}}}
 71
 72	//{{{ getVirtualLineCount() method
 73	/**
 74	 * Returns the number of virtual lines in the buffer.
 75	 * @since jEdit 4.0pre1
 76	 */
 77	public int getVirtualLineCount()
 78	{
 79		return offsetMgr.getVirtualLineCount(index);
 80	} //}}}
 81
 82	//{{{ isLineVisible() method
 83	/**
 84	 * Returns if the specified line is visible.
 85	 * @param line A physical line index
 86	 * @since jEdit 4.0pre1
 87	 */
 88	public final boolean isLineVisible(int line)
 89	{
 90		if(line < 0 || line >= offsetMgr.getLineCount())
 91			throw new ArrayIndexOutOfBoundsException(line);
 92
 93		try
 94		{
 95			buffer.readLock();
 96			return offsetMgr.isLineVisible(line,index);
 97		}
 98		finally
 99		{
100			buffer.readUnlock();
101		}
102	} //}}}
103
104	//{{{ getFirstVisibleLine() method
105	/**
106	 * Returns the physical line number of the first visible line.
107	 * @since jEdit 4.0pre3
108	 */
109	public int getFirstVisibleLine()
110	{
111		try
112		{
113			buffer.readLock();
114
115			for(int i = 0; i < buffer.getLineCount(); i++)
116			{
117				if(offsetMgr.isLineVisible(i,index))
118					return i;
119			}
120		}
121		finally
122		{
123			buffer.readUnlock();
124		}
125
126		// can't happen?
127		return -1;
128	} //}}}
129
130	//{{{ getLastVisibleLine() method
131	/**
132	 * Returns the physical line number of the last visible line.
133	 * @since jEdit 4.0pre3
134	 */
135	public int getLastVisibleLine()
136	{
137		try
138		{
139			buffer.readLock();
140
141			for(int i = buffer.getLineCount() - 1; i >= 0; i--)
142			{
143				if(offsetMgr.isLineVisible(i,index))
144					return i;
145			}
146		}
147		finally
148		{
149			buffer.readUnlock();
150		}
151
152		// can't happen?
153		return -1;
154	} //}}}
155
156	//{{{ getNextVisibleLine() method
157	/**
158	 * Returns the next visible line after the specified line index.
159	 * @param line A physical line index
160	 * @since jEdit 4.0pre1
161	 */
162	public int getNextVisibleLine(int line)
163	{
164		if(line < 0 || line >= offsetMgr.getLineCount())
165			throw new ArrayIndexOutOfBoundsException(line);
166
167		try
168		{
169			buffer.readLock();
170
171			if(line == buffer.getLineCount() - 1)
172				return -1;
173
174			for(int i = line + 1; i < buffer.getLineCount(); i++)
175			{
176				if(offsetMgr.isLineVisible(i,index))
177					return i;
178			}
179			return -1;
180		}
181		finally
182		{
183			buffer.readUnlock();
184		}
185	} //}}}
186
187	//{{{ getPrevVisibleLine() method
188	/**
189	 * Returns the previous visible line before the specified line index.
190	 * @param line A physical line index
191	 * @since jEdit 4.0pre1
192	 */
193	public int getPrevVisibleLine(int line)
194	{
195		if(line < 0 || line >= offsetMgr.getLineCount())
196			throw new ArrayIndexOutOfBoundsException(line);
197
198		try
199		{
200			buffer.readLock();
201
202			if(line == 0)
203				return -1;
204
205			for(int i = line - 1; i >= 0; i--)
206			{
207				if(offsetMgr.isLineVisible(i,index))
208					return i;
209			}
210			return -1;
211		}
212		finally
213		{
214			buffer.readUnlock();
215		}
216	} //}}}
217
218	//{{{ physicalToVirtual() method
219	/**
220	 * Converts a physical line number to a virtual line number.
221	 * @param line A physical line index
222	 * @since jEdit 4.0pre1
223	 */
224	public int physicalToVirtual(int line)
225	{
226		try
227		{
228			buffer.readLock();
229
230			if(line < 0)
231				throw new ArrayIndexOutOfBoundsException(line + " < 0");
232			else if(line >= offsetMgr.getLineCount())
233			{
234				throw new ArrayIndexOutOfBoundsException(line + " > "
235					+ buffer.getLineCount());
236			}
237
238			while(!offsetMgr.isLineVisible(line,index) && line > 0)
239				line--;
240
241			if(line == 0 && !offsetMgr.isLineVisible(line,index))
242			{
243				// inside the top narrow.
244				return 0;
245			}
246
247			if(lastPhysical == line)
248			{
249				if(lastVirtual < 0 || lastVirtual >= offsetMgr.getVirtualLineCount(index))
250				{
251					throw new ArrayIndexOutOfBoundsException(
252						"cached: " + lastVirtual);
253				}
254			}
255			else if(line > lastPhysical && lastPhysical != -1)
256			{
257				for(;;)
258				{
259					if(lastPhysical == line)
260						break;
261
262					if(offsetMgr.isLineVisible(lastPhysical,index))
263						lastVirtual++;
264
265					if(lastPhysical == buffer.getLineCount() - 1)
266						break;
267					else
268						lastPhysical++;
269				}
270
271				if(lastVirtual < 0 || lastVirtual >= offsetMgr.getVirtualLineCount(index))
272				{
273					throw new ArrayIndexOutOfBoundsException(
274						"fwd scan: " + lastVirtual);
275				}
276			}
277			else if(line < lastPhysical && lastPhysical - line > line)
278			{
279				for(;;)
280				{
281					if(lastPhysical == line)
282						break;
283
284					if(offsetMgr.isLineVisible(lastPhysical,index))
285						lastVirtual--;
286
287					if(lastPhysical == 0)
288						break;
289					else
290						lastPhysical--;
291				}
292
293				if(lastVirtual < 0 || lastVirtual >= offsetMgr.getVirtualLineCount(index))
294				{
295					throw new ArrayIndexOutOfBoundsException(
296						"back scan: " + lastVirtual);
297				}
298			}
299			else
300			{
301				lastPhysical = 0;
302				// find first visible line
303				while(!offsetMgr.isLineVisible(lastPhysical,index))
304					lastPhysical++;
305
306				lastVirtual = 0;
307				for(;;)
308				{
309					if(lastPhysical == line)
310						break;
311
312					if(offsetMgr.isLineVisible(lastPhysical,index))
313						lastVirtual++;
314
315					if(lastPhysical == buffer.getLineCount() - 1)
316						break;
317					else
318						lastPhysical++;
319				}
320
321				if(lastVirtual < 0 || lastVirtual >= offsetMgr.getVirtualLineCount(index))
322				{
323					throw new ArrayIndexOutOfBoundsException(
324						"zero scan: " + lastVirtual);
325				}
326			}
327
328			return lastVirtual;
329		}
330		finally
331		{
332			buffer.readUnlock();
333		}
334	} //}}}
335
336	//{{{ virtualToPhysical() method
337	/**
338	 * Converts a virtual line number to a physical line number.
339	 * @param line A virtual line index
340	 * @since jEdit 4.0pre1
341	 */
342	public int virtualToPhysical(int line)
343	{
344		try
345		{
346			buffer.readLock();
347
348			if(line < 0)
349				throw new ArrayIndexOutOfBoundsException(line + " < 0");
350			else if(line >= offsetMgr.getVirtualLineCount(index))
351			{
352				throw new ArrayIndexOutOfBoundsException(line + " > "
353					+ offsetMgr.getVirtualLineCount(index));
354			}
355
356			if(lastVirtual == line)
357			{
358				if(lastPhysical < 0 || lastPhysical >= buffer.getLineCount())
359				{
360					throw new ArrayIndexOutOfBoundsException(
361						"cached: " + lastPhysical);
362				}
363			}
364			else if(line > lastVirtual && lastVirtual != -1)
365			{
366				for(;;)
367				{
368					if(offsetMgr.isLineVisible(lastPhysical,index))
369					{
370						if(lastVirtual == line)
371							break;
372						else
373							lastVirtual++;
374					}
375
376					if(lastPhysical == buffer.getLineCount() - 1)
377						break;
378					else
379						lastPhysical++;
380				}
381
382				if(lastPhysical < 0 || lastPhysical >= buffer.getLineCount())
383				{
384					throw new ArrayIndexOutOfBoundsException(
385						"fwd scan: " + lastPhysical);
386				}
387			}
388			else if(line < lastVirtual && lastVirtual - line > line)
389			{
390				for(;;)
391				{
392					if(offsetMgr.isLineVisible(lastPhysical,index))
393					{
394						if(lastVirtual == line)
395							break;
396						else
397							lastVirtual--;
398					}
399
400					if(lastPhysical == 0)
401						break;
402					else
403						lastPhysical--;
404				}
405
406				if(lastPhysical < 0 || lastPhysical >= buffer.getLineCount())
407				{
408					throw new ArrayIndexOutOfBoundsException(
409						"back scan: " + lastPhysical);
410				}
411			}
412			else
413			{
414
415				lastPhysical = 0;
416				// find first visible line
417				while(!offsetMgr.isLineVisible(lastPhysical,index))
418					lastPhysical++;
419
420				lastVirtual = 0;
421				for(;;)
422				{
423					if(offsetMgr.isLineVisible(lastPhysical,index))
424					{
425						if(lastVirtual == line)
426							break;
427						else
428							lastVirtual++;
429					}
430
431					if(lastPhysical == buffer.getLineCount() - 1)
432						break;
433					else
434						lastPhysical++;
435				}
436
437				if(lastPhysical < 0 || lastPhysical >= buffer.getLineCount())
438				{
439					throw new ArrayIndexOutOfBoundsException(
440						"zero scan: " + lastPhysical);
441				}
442			}
443
444			return lastPhysical;
445		}
446		finally
447		{
448			buffer.readUnlock();
449		}
450	} //}}}
451
452	//{{{ collapseFold() method
453	/**
454	 * Collapses the fold at the specified physical line index.
455	 * @param line A physical line index
456	 * @since jEdit 4.0pre1
457	 */
458	public void collapseFold(int line)
459	{
460		int lineCount = buffer.getLineCount();
461		int start = 0;
462		int end = lineCount - 1;
463
464		try
465		{
466			buffer.writeLock();
467
468			// if the caret is on a collapsed fold, collapse the
469			// parent fold
470			if(line != 0
471				&& line != buffer.getLineCount() - 1
472				&& buffer.isFoldStart(line)
473				&& !offsetMgr.isLineVisible(line + 1,index))
474			{
475				line--;
476			}
477
478			int initialFoldLevel = buffer.getFoldLevel(line);
479
480			//{{{ Find fold start and end...
481			if(line != lineCount - 1
482				&& buffer.getFoldLevel(line + 1) > initialFoldLevel)
483			{
484				// this line is the start of a fold
485				start = line + 1;
486
487				for(int i = line + 1; i < lineCount; i++)
488				{
489					if(buffer.getFoldLevel(i) <= initialFoldLevel)
490					{
491						end = i - 1;
492						break;
493					}
494				}
495			}
496			else
497			{
498				boolean ok = false;
499
500				// scan backwards looking for the start
501				for(int i = line - 1; i >= 0; i--)
502				{
503					if(buffer.getFoldLevel(i) < initialFoldLevel)
504					{
505						start = i + 1;
506						ok = true;
507						break;
508					}
509				}
510
511				if(!ok)
512				{
513					// no folds in buffer
514					return;
515				}
516
517				for(int i = line + 1; i < lineCount; i++)
518				{
519					if(buffer.getFoldLevel(i) < initialFoldLevel)
520					{
521						end = i - 1;
522						break;
523					}
524				}
525			} //}}}
526
527			//{{{ Collapse the fold...
528			int delta = (end - start + 1);
529
530			for(int i = start; i <= end; i++)
531			{
532				if(offsetMgr.isLineVisible(i,index))
533					offsetMgr.setLineVisible(i,index,false);
534				else
535					delta--;
536			}
537
538			if(delta == 0)
539			{
540				// user probably pressed A+BACK_SPACE twice
541				return;
542			}
543
544			offsetMgr.setVirtualLineCount(index,
545				offsetMgr.getVirtualLineCount(index)
546				- delta);
547			//}}}
548		}
549		finally
550		{
551			buffer.writeUnlock();
552		}
553
554		foldStructureChanged();
555
556		int virtualLine = physicalToVirtual(start);
557		if(textArea.getFirstLine() > virtualLine)
558			textArea.setFirstLine(virtualLine - textArea.getElectricScroll());
559	} //}}}
560
561	//{{{ expandFold() method
562	/**
563	 * Expands the fold at the specified physical line index.
564	 * @param line A physical line index
565	 * @param fully If true, all subfolds will also be expanded
566	 * @since jEdit 4.0pre3
567	 */
568	public int expandFold(int line, boolean fully)
569	{
570		// the first sub-fold. used by JEditTextArea.expandFold().
571		int returnValue = -1;
572
573		int lineCount = buffer.getLineCount();
574		int start = 0;
575		int end = lineCount - 1;
576		int delta = 0;
577
578		try
579		{
580			buffer.writeLock();
581
582			int initialFoldLevel = buffer.getFoldLevel(line);
583
584			//{{{ Find fold start and fold end...
585			if(line != lineCount - 1
586				&& offsetMgr.isLineVisible(line,index)
587				&& !offsetMgr.isLineVisible(line + 1,index)
588				&& buffer.getFoldLevel(line + 1) > initialFoldLevel)
589			{
590				// this line is the start of a fold
591				start = line + 1;
592
593				for(int i = line + 1; i < lineCount; i++)
594				{
595					if(/* offsetMgr.isLineVisible(i,index) && */
596						buffer.getFoldLevel(i) <= initialFoldLevel)
597					{
598						end = i - 1;
599						break;
600					}
601				}
602			}
603			else
604			{
605				boolean ok = false;
606
607				// scan backwards looking for the start
608				for(int i = line - 1; i >= 0; i--)
609				{
610					if(offsetMgr.isLineVisible(i,index) && buffer.getFoldLevel(i) < initialFoldLevel)
611					{
612						start = i + 1;
613						ok = true;
614						break;
615					}
616				}
617
618				if(!ok)
619				{
620					// no folds in buffer
621					return -1;
622				}
623
624				for(int i = line + 1; i < lineCount; i++)
625				{
626					if((offsetMgr.isLineVisible(i,index) &&
627						buffer.getFoldLevel(i) < initialFoldLevel)
628						|| i == getLastVisibleLine())
629					{
630						end = i - 1;
631						break;
632					}
633				}
634			} //}}}
635
636			//{{{ Expand the fold...
637
638			// we need a different value of initialFoldLevel here!
639			initialFoldLevel = buffer.getFoldLevel(start);
640
641			for(int i = start; i <= end; i++)
642			{
643				buffer.getFoldLevel(i);
644			}
645
646			for(int i = start; i <= end; i++)
647			{
648				if(buffer.getFoldLevel(i) > initialFoldLevel)
649				{
650					if(returnValue == -1
651						&& i != 0
652						&& buffer.isFoldStart(i - 1))
653					{
654						returnValue = i - 1;
655					}
656
657					if(!offsetMgr.isLineVisible(i,index) && fully)
658					{
659						delta++;
660						offsetMgr.setLineVisible(i,index,true);
661					}
662				}
663				else if(!offsetMgr.isLineVisible(i,index))
664				{
665					delta++;
666					offsetMgr.setLineVisible(i,index,true);
667				}
668			}
669
670			offsetMgr.setVirtualLineCount(index,
671				offsetMgr.getVirtualLineCount(index)
672				+ delta);
673			//}}}
674
675			if(!fully && !offsetMgr.isLineVisible(line,index))
676			{
677				// this is a hack, and really needs to be done better.
678				expandFold(line,false);
679				return returnValue;
680			}
681		}
682		finally
683		{
684			buffer.writeUnlock();
685		}
686
687		foldStructureChanged();
688
689		int virtualLine = physicalToVirtual(start);
690		int firstLine = textArea.getFirstLine();
691		int visibleLines = textArea.getVisibleLines();
692		if(virtualLine + delta >= firstLine + visibleLines
693			&& delta < visibleLines - 1)
694		{
695			textArea.setFirstLine(virtualLine + delta - visibleLines + 1);
696		}
697
698		return returnValue;
699	} //}}}
700
701	//{{{ expandAllFolds() method
702	/**
703	 * Expands all folds.
704	 * @since jEdit 4.0pre1
705	 */
706	public void expandAllFolds()
707	{
708		try
709		{
710			buffer.writeLock();
711
712			narrowed = false;
713
714			offsetMgr.setVirtualLineCount(index,buffer.getLineCount());
715			for(int i = 0; i < buffer.getLineCount(); i++)
716			{
717				offsetMgr.setLineVisible(i,index,true);
718			}
719			foldStructureChanged();
720		}
721		finally
722		{
723			buffer.writeUnlock();
724		}
725	} //}}}
726
727	//{{{ expandFolds() method
728	/**
729	 * This method should only be called from <code>actions.xml</code>.
730	 * @since jEdit 4.0pre1
731	 */
732	public void expandFolds(char digit)
733	{
734		if(digit < '1' || digit > '9')
735		{
736			Toolkit.getDefaultToolkit().beep();
737			return;
738		}
739		else
740			expandFolds((int)(digit - '1') + 1);
741	} //}}}
742
743	//{{{ expandFolds() method
744	/**
745	 * Expands all folds with the specified fold level.
746	 * @param foldLevel The fold level
747	 * @since jEdit 4.0pre1
748	 */
749	public void expandFolds(int foldLevel)
750	{
751		try
752		{
753			buffer.writeLock();
754
755			narrowed = false;
756
757			// so that getFoldLevel() calling fireFoldLevelsChanged()
758			// won't break
759			offsetMgr.setVirtualLineCount(index,buffer.getLineCount());
760
761			int newVirtualLineCount = 0;
762			foldLevel = (foldLevel - 1) * buffer.getIndentSize() + 1;
763
764			/* this ensures that the first line is always visible */
765			boolean seenVisibleLine = false;
766
767			for(int i = 0; i < buffer.getLineCount(); i++)
768			{
769				if(!seenVisibleLine || buffer.getFoldLevel(i) < foldLevel)
770				{
771					seenVisibleLine = true;
772					offsetMgr.setLineVisible(i,index,true);
773					newVirtualLineCount++;
774				}
775				else
776					offsetMgr.setLineVisible(i,index,false);
777			}
778
779			offsetMgr.setVirtualLineCount(index,newVirtualLineCount);
780		}
781		finally
782		{
783			buffer.writeUnlock();
784		}
785
786		foldStructureChanged();
787	} //}}}
788
789	//{{{ narrow() method
790	/**
791	 * Narrows the visible portion of the buffer to the specified
792	 * line range.
793	 * @param start The first line
794	 * @param end The last line
795	 * @since jEdit 4.0pre1
796	 */
797	public void narrow(int start, int end)
798	{
799		if(start > end || start < 0 || end >= offsetMgr.getLineCount())
800			throw new ArrayIndexOutOfBoundsException(start + ", " + end);
801
802		// ideally, this should somehow be rolled into the below loop.
803		if(start != offsetMgr.getLineCount() - 1
804			&& !offsetMgr.isLineVisible(start + 1,index))
805			expandFold(start,false);
806
807		int virtualLineCount = offsetMgr.getVirtualLineCount(index);
808		for(int i = 0; i < start; i++)
809		{
810			if(offsetMgr.isLineVisible(i,index))
811			{
812				virtualLineCount--;
813				offsetMgr.setLineVisible(i,index,false);
814			}
815		}
816
817		for(int i = end + 1; i < buffer.getLineCount(); i++)
818		{
819			if(offsetMgr.isLineVisible(i,index))
820			{
821				virtualLineCount--;
822				offsetMgr.setLineVisible(i,index,false);
823			}
824		}
825
826		offsetMgr.setVirtualLineCount(index,virtualLineCount);
827
828		narrowed = true;
829
830		foldStructureChanged();
831
832		// Hack... need a more direct way of obtaining a view?
833		// JEditTextArea.getView() method?
834		GUIUtilities.getView(textArea).getStatus().setMessageAndClear(
835			jEdit.getProperty("view.status.narrow"));
836	} //}}}
837
838	//{{{ Methods for Buffer class to call
839
840	//{{{ _grab() method
841	/**
842	 * Do not call this method. The only reason it is public is so
843	 * that the <code>Buffer</code> class can call it.
844	 */
845	public final void _grab(int index)
846	{
847		this.index = index;
848		lastPhysical = lastVirtual = -1;
849	} //}}}
850
851	//{{{ _release() method
852	/**
853	 * Do not call this method. The only reason it is public is so
854	 * that the <code>Buffer</code> class can call it.
855	 */
856	public final void _release()
857	{
858		index = -1;
859	} //}}}
860
861	//{{{ _getIndex() method
862	/**
863	 * Do not call this method. The only reason it is public is so
864	 * that the <code>Buffer</code> class can call it.
865	 */
866	public final int _getIndex()
867	{
868		return index;
869	} //}}}
870
871	//{{{ _invalidate() method
872	/**
873	 * Do not call this method. The only reason it is public is so
874	 * that the <code>Buffer</code> class can call it.
875	 */
876	public void _invalidate(int startLine)
877	{
878		if(lastPhysical >= startLine)
879			lastPhysical = lastVirtual = 0;
880	} //}}}
881
882	//}}}
883
884	//{{{ Private members
885
886	//{{{ Instance variables
887	private Buffer buffer;
888	private OffsetManager offsetMgr;
889	private JEditTextArea textArea;
890	private int index;
891	private int lastPhysical;
892	private int lastVirtual;
893	private boolean narrowed;
894	//}}}
895
896	//{{{ foldStructureChanged() method
897	private void foldStructureChanged()
898	{
899		lastPhysical = lastVirtual = -1;
900		textArea.foldStructureChanged();
901	} //}}}
902
903	//}}}
904}