18 #include "katetemplatehandler.h"
19 #include "katetemplatehandler.moc"
20 #include "katedocument.h"
21 #include "katesupercursor.h"
22 #include "katearbitraryhighlight.h"
26 #include <tqvaluelist.h>
28 KateTemplateHandler::KateTemplateHandler(
30 uint line, uint column,
31 const TQString &templateString,
32 const TQMap<TQString, TQString> &initialValues )
34 , KateKeyInterceptorFunctor()
36 , m_currentTabStop( -1 )
39 , m_recursion( false )
41 connect( m_doc, TQ_SIGNAL( destroyed() ),
this, TQ_SLOT( slotDocumentDestroyed() ) );
42 m_ranges =
new KateSuperRangeList(
false,
this );
44 if ( !m_doc->setTabInterceptor(
this ) )
56 TQValueList<KateTemplateHandlerPlaceHolderInfo> buildList;
57 TQRegExp rx(
"([$%])\\{([^}\\s]+)\\}" );
58 rx.setMinimal(
true );
61 TQString insertString = templateString;
65 pos = rx.search( insertString, pos );
69 if ( ( pos - opos ) > 0 )
71 if ( insertString[ pos - 1 ] ==
'\\' )
73 insertString.remove( pos - 1, 1 );
79 TQString placeholder = rx.cap( 2 );
80 TQString value = initialValues[ placeholder ];
83 if ( rx.cap( 1 ) !=
"%" || placeholder == value )
84 buildList.append( KateTemplateHandlerPlaceHolderInfo( pos, value.length(), placeholder ) );
86 insertString.replace( pos, rx.matchedLength(), value );
87 pos += value.length();
94 if ( !doc->insertText( line, column, insertString ) )
101 if ( buildList.isEmpty() )
109 doc->undoSafePoint();
111 generateRangeTable( line, column, insertString, buildList );
112 kah->addHighlightToDocument( m_ranges );
114 for ( KateSuperRangeList::const_iterator it = m_ranges->begin();it != m_ranges->end();++it )
116 m_doc->tagLines( ( *it ) ->start().line(), ( *it ) ->end().line() );
123 connect( doc, TQ_SIGNAL( textInserted(
int,
int ) ),
this, TQ_SLOT( slotTextInserted(
int,
int ) ) );
124 connect( doc, TQ_SIGNAL( aboutToRemoveText(
const KateTextRange& ) ),
this, TQ_SLOT( slotAboutToRemoveText(
const KateTextRange& ) ) );
125 connect( doc, TQ_SIGNAL( textRemoved() ),
this, TQ_SLOT( slotTextRemoved() ) );
127 ( *this ) ( TQt::Key_Tab );
130 KateTemplateHandler::~KateTemplateHandler()
132 m_ranges->setAutoManage(
true );
136 m_doc->removeTabInterceptor(
this );
138 for ( KateSuperRangeList::const_iterator it = m_ranges->begin();it != m_ranges->end();++it )
140 m_doc->tagLines( ( *it ) ->start().line(), ( *it ) ->end().line() );
147 void KateTemplateHandler::slotDocumentDestroyed() {m_doc = 0;}
149 void KateTemplateHandler::generateRangeTable( uint insertLine, uint insertCol,
const TQString& insertString,
const TQValueList<KateTemplateHandlerPlaceHolderInfo> &buildList )
151 uint line = insertLine;
152 uint col = insertCol;
155 for ( TQValueList<KateTemplateHandlerPlaceHolderInfo>::const_iterator it = buildList.begin();it != buildList.end();++it )
157 KateTemplatePlaceHolder *ph = m_dict[ ( *it ).placeholder ];
161 ph =
new KateTemplatePlaceHolder;
162 ph->isInitialValue =
true;
163 ph->isCursor = ( ( *it ).placeholder ==
"cursor" );
164 m_dict.insert( ( *it ).placeholder, ph );
166 if ( !ph->isCursor ) m_tabOrder.append( ph );
168 ph->ranges.setAutoManage(
false );
172 while ( colInText < ( *it ).begin )
176 if ( insertString.at( colInText ) ==
'\n' )
185 KateArbitraryHighlightRange *hlr =
new KateArbitraryHighlightRange( m_doc,
KateTextCursor( line, col ),
187 colInText += ( *it ).len;
189 hlr->allowZeroLength();
190 hlr->setUnderline(
true );
191 hlr->setOverline(
true );
193 ph->ranges.append( hlr );
194 m_ranges->append( hlr );
197 KateTemplatePlaceHolder *cursor = m_dict[
"cursor" ];
199 if ( cursor ) m_tabOrder.append( cursor );
202 void KateTemplateHandler::slotTextInserted(
int line,
int col )
205 #warning FIXME undo/redo detection
208 if ( m_recursion ) return ;
213 if ( ( !m_currentRange ) ||
214 ( ( !m_currentRange->includes( cur ) ) && ( ! ( ( m_currentRange->start() == m_currentRange->end() ) && m_currentRange->end() == cur ) )
215 ) ) locateRange( cur );
217 if ( !m_currentRange ) return ;
219 KateTemplatePlaceHolder *ph = m_tabOrder.at( m_currentTabStop );
221 TQString sourceText = m_doc->text ( m_currentRange->start().line(), m_currentRange->start().col(),
222 m_currentRange->end().line(), m_currentRange->end().col(),
false );
224 ph->isInitialValue =
false;
225 bool undoDontMerge = m_doc->m_undoDontMerge;
226 Q_ASSERT( m_doc->editSessionNumber == 0 );
231 for ( KateSuperRangeList::const_iterator it = ph->ranges.begin();it != ph->ranges.end();++it )
233 if ( ( *it ) == m_currentRange )
continue;
237 m_doc->removeText( start.line(), start.col(),
end.line(),
end.col(),
false );
238 m_doc->insertText( start.line(), start.col(), sourceText );
241 m_doc->m_undoDontMerge =
false;
242 m_doc->m_undoComplexMerge =
true;
243 m_doc->undoSafePoint();
245 m_doc->m_undoDontMerge = undoDontMerge;
248 if ( ph->isCursor ) deleteLater();
251 void KateTemplateHandler::locateRange(
const KateTextCursor& cursor )
258 for ( uint i = 0;i < m_tabOrder.count();i++ )
260 KateTemplatePlaceHolder *ph = m_tabOrder.at( i );
262 for ( KateSuperRangeList::const_iterator it = ph->ranges.begin();it != ph->ranges.end();++it )
264 if ( ( *it ) ->includes( cursor ) )
266 m_currentTabStop = i;
267 m_currentRange = ( *it );
284 bool KateTemplateHandler::operator() (
KKey key )
286 if ( key==TQt::Key_Tab )
290 if ( m_currentTabStop >= (
int ) m_tabOrder.count() )
291 m_currentTabStop = 0;
297 if ( m_currentTabStop < 0 ) m_currentTabStop = m_tabOrder.count() - 1;
300 m_currentRange = m_tabOrder.at( m_currentTabStop ) ->ranges.at( 0 );
302 if ( m_tabOrder.at( m_currentTabStop ) ->isInitialValue )
304 m_doc->activeView()->setSelection( m_currentRange->start(), m_currentRange->end() );
306 else m_doc->activeView()->setSelection( m_currentRange->end(), m_currentRange->end() );
308 m_doc->activeView() ->setCursorPositionReal( m_currentRange->end().line(), m_currentRange->end().col() );
309 m_doc->activeView() ->tagLine( m_currentRange->end() );
314 void KateTemplateHandler::slotAboutToRemoveText(
const KateTextRange &range )
316 if ( m_recursion ) return ;
318 if ( m_currentRange && ( !m_currentRange->includes( range.start() ) ) ) locateRange( range.start() );
320 if ( m_currentRange != 0 )
322 if ( m_currentRange->end() <= range.end() ) return ;
327 disconnect( m_doc, TQ_SIGNAL( textInserted(
int,
int ) ),
this, TQ_SLOT( slotTextInserted(
int,
int ) ) );
328 disconnect( m_doc, TQ_SIGNAL( aboutToRemoveText(
const KateTextRange& ) ),
this, TQ_SLOT( slotAboutToRemoveText(
const KateTextRange& ) ) );
329 disconnect( m_doc, TQ_SIGNAL( textRemoved() ),
this, TQ_SLOT( slotTextRemoved() ) );
335 void KateTemplateHandler::slotTextRemoved()
337 if ( m_recursion ) return ;
338 if ( !m_currentRange ) return ;
340 slotTextInserted( m_currentRange->start().line(), m_currentRange->start().col() );
An arbitrary highlighting interface for Kate.
Simple cursor class with no document pointer.
const TDEShortcut & end()