• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kate
 

kate

  • kate
  • part
katetemplatehandler.cpp
1/* This file is part of the KDE libraries
2 Copyright (C) 2004 Joseph Wenninger <jowenn@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
17*/
18#include "katetemplatehandler.h"
19#include "katetemplatehandler.moc"
20#include "katedocument.h"
21#include "katesupercursor.h"
22#include "katearbitraryhighlight.h"
23#include "kateview.h"
24#include <tqregexp.h>
25#include <kdebug.h>
26#include <tqvaluelist.h>
27
28KateTemplateHandler::KateTemplateHandler(
29 KateDocument *doc,
30 uint line, uint column,
31 const TQString &templateString,
32 const TQMap<TQString, TQString> &initialValues )
33 : TQObject( doc )
34 , KateKeyInterceptorFunctor()
35 , m_doc( doc )
36 , m_currentTabStop( -1 )
37 , m_currentRange( 0 )
38 , m_initOk( false )
39 , m_recursion( false )
40{
41 connect( m_doc, TQ_SIGNAL( destroyed() ), this, TQ_SLOT( slotDocumentDestroyed() ) );
42 m_ranges = new KateSuperRangeList( false, this ); //false/*,this*/);
43
44 if ( !m_doc->setTabInterceptor( this ) )
45 {
46 deleteLater();
47 return ;
48 }
49
50 KateArbitraryHighlight *kah = doc->arbitraryHL();
51 /*KateArbitraryHighlightRange *hlr=new KateArbitraryHighlightRange(doc,KateTextCursor(line,column),
52 KateTextCursor(line,column+3));
53 hlr->setUnderline(true);
54 hlr->setOverline(true);
55 l->append(hlr);*/
56 TQValueList<KateTemplateHandlerPlaceHolderInfo> buildList;
57 TQRegExp rx( "([$%])\\{([^}\\s]+)\\}" );
58 rx.setMinimal( true );
59 int pos = 0;
60 int opos = 0;
61 TQString insertString = templateString;
62
63 while ( pos >= 0 )
64 {
65 pos = rx.search( insertString, pos );
66
67 if ( pos > -1 )
68 {
69 if ( ( pos - opos ) > 0 )
70 {
71 if ( insertString[ pos - 1 ] == '\\' )
72 {
73 insertString.remove( pos - 1, 1 );
74 opos = pos;
75 continue;
76 }
77 }
78
79 TQString placeholder = rx.cap( 2 );
80 TQString value = initialValues[ placeholder ];
81
82 // don't add %{MACRO} to the tab navigation, unless there was not value
83 if ( rx.cap( 1 ) != "%" || placeholder == value )
84 buildList.append( KateTemplateHandlerPlaceHolderInfo( pos, value.length(), placeholder ) );
85
86 insertString.replace( pos, rx.matchedLength(), value );
87 pos += value.length();
88 opos = pos;
89 }
90 }
91
92 doc->editStart();
93
94 if ( !doc->insertText( line, column, insertString ) )
95 {
96 deleteLater();
97 doc->editEnd();
98 return ;
99 }
100
101 if ( buildList.isEmpty() )
102 {
103 m_initOk = true;
104 deleteLater();
105 doc->editEnd();
106 return ;
107 }
108
109 doc->undoSafePoint();
110 doc->editEnd();
111 generateRangeTable( line, column, insertString, buildList );
112 kah->addHighlightToDocument( m_ranges );
113
114 for ( KateSuperRangeList::const_iterator it = m_ranges->begin();it != m_ranges->end();++it )
115 {
116 m_doc->tagLines( ( *it ) ->start().line(), ( *it ) ->end().line() );
117 }
118
119 /* connect(doc,TQ_SIGNAL(charactersInteractivelyInserted(int ,int ,const TQString&)),this,
120 TQ_SLOT(slotCharactersInteractivlyInserted(int,int,const TQString&)));
121 connect(doc,TQ_SIGNAL(charactersSemiInteractivelyInserted(int ,int ,const TQString&)),this,
122 TQ_SLOT(slotCharactersInteractivlyInserted(int,int,const TQString&)));*/
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() ) );
126
127 ( *this ) ( TQt::Key_Tab );
128}
129
130KateTemplateHandler::~KateTemplateHandler()
131{
132 m_ranges->setAutoManage( true );
133
134 if ( m_doc )
135 {
136 m_doc->removeTabInterceptor( this );
137
138 for ( KateSuperRangeList::const_iterator it = m_ranges->begin();it != m_ranges->end();++it )
139 {
140 m_doc->tagLines( ( *it ) ->start().line(), ( *it ) ->end().line() );
141 }
142 }
143
144 m_ranges->clear();
145}
146
147void KateTemplateHandler::slotDocumentDestroyed() {m_doc = 0;}
148
149void KateTemplateHandler::generateRangeTable( uint insertLine, uint insertCol, const TQString& insertString, const TQValueList<KateTemplateHandlerPlaceHolderInfo> &buildList )
150{
151 uint line = insertLine;
152 uint col = insertCol;
153 uint colInText = 0;
154
155 for ( TQValueList<KateTemplateHandlerPlaceHolderInfo>::const_iterator it = buildList.begin();it != buildList.end();++it )
156 {
157 KateTemplatePlaceHolder *ph = m_dict[ ( *it ).placeholder ];
158
159 if ( !ph )
160 {
161 ph = new KateTemplatePlaceHolder;
162 ph->isInitialValue = true;
163 ph->isCursor = ( ( *it ).placeholder == "cursor" );
164 m_dict.insert( ( *it ).placeholder, ph );
165
166 if ( !ph->isCursor ) m_tabOrder.append( ph );
167
168 ph->ranges.setAutoManage( false );
169 }
170
171 // FIXME handle space/tab replacement correctly make it use of the indenter
172 while ( colInText < ( *it ).begin )
173 {
174 ++col;
175
176 if ( insertString.at( colInText ) == '\n' )
177 {
178 col = 0;
179 line++;
180 }
181
182 ++colInText;
183 }
184
185 KateArbitraryHighlightRange *hlr = new KateArbitraryHighlightRange( m_doc, KateTextCursor( line, col ),
186 KateTextCursor( line, ( *it ).len + col ) );
187 colInText += ( *it ).len;
188 col += ( *it ).len;
189 hlr->allowZeroLength();
190 hlr->setUnderline( true );
191 hlr->setOverline( true );
192 //hlr->setBehaviour(KateSuperRange::ExpandRight);
193 ph->ranges.append( hlr );
194 m_ranges->append( hlr );
195 }
196
197 KateTemplatePlaceHolder *cursor = m_dict[ "cursor" ];
198
199 if ( cursor ) m_tabOrder.append( cursor );
200}
201
202void KateTemplateHandler::slotTextInserted( int line, int col )
203{
204#ifdef __GNUC__
205#warning FIXME undo/redo detection
206#endif
207
208 if ( m_recursion ) return ;
209
210 //if (m_editSessionNumber!=0) return; // assume that this is due an udno/redo operation right now
211 KateTextCursor cur( line, col );
212
213 if ( ( !m_currentRange ) ||
214 ( ( !m_currentRange->includes( cur ) ) && ( ! ( ( m_currentRange->start() == m_currentRange->end() ) && m_currentRange->end() == cur ) )
215 ) ) locateRange( cur );
216
217 if ( !m_currentRange ) return ;
218
219 KateTemplatePlaceHolder *ph = m_tabOrder.at( m_currentTabStop );
220
221 TQString sourceText = m_doc->text ( m_currentRange->start().line(), m_currentRange->start().col(),
222 m_currentRange->end().line(), m_currentRange->end().col(), false );
223
224 ph->isInitialValue = false;
225 bool undoDontMerge = m_doc->m_undoDontMerge;
226 Q_ASSERT( m_doc->editSessionNumber == 0 );
227 m_recursion = true;
228
229 m_doc->editStart( /*false*/ );
230
231 for ( KateSuperRangeList::const_iterator it = ph->ranges.begin();it != ph->ranges.end();++it )
232 {
233 if ( ( *it ) == m_currentRange ) continue;
234
235 KateTextCursor start = ( *it ) ->start();
236 KateTextCursor end = ( *it ) ->end();
237 m_doc->removeText( start.line(), start.col(), end.line(), end.col(), false );
238 m_doc->insertText( start.line(), start.col(), sourceText );
239 }
240
241 m_doc->m_undoDontMerge = false;
242 m_doc->m_undoComplexMerge = true;
243 m_doc->undoSafePoint();
244 m_doc->editEnd();
245 m_doc->m_undoDontMerge = undoDontMerge;
246 m_recursion = false;
247
248 if ( ph->isCursor ) deleteLater();
249}
250
251void KateTemplateHandler::locateRange( const KateTextCursor& cursor )
252{
253 /* if (m_currentRange) {
254 m_doc->tagLines(m_currentRange->start().line(),m_currentRange->end().line());
255
256 }*/
257
258 for ( uint i = 0;i < m_tabOrder.count();i++ )
259 {
260 KateTemplatePlaceHolder *ph = m_tabOrder.at( i );
261
262 for ( KateSuperRangeList::const_iterator it = ph->ranges.begin();it != ph->ranges.end();++it )
263 {
264 if ( ( *it ) ->includes( cursor ) )
265 {
266 m_currentTabStop = i;
267 m_currentRange = ( *it );
268 //m_doc->tagLines(m_currentRange->start().line(),m_currentRange->end().line());
269 return ;
270 }
271 }
272
273 }
274
275 m_currentRange = 0;
276 /*while (m_ranges->count()>0)
277 delete (m_ranges->take(0));
278 disconnect(m_ranges,0,0,0);
279 delete m_ranges;*/
280 deleteLater();
281}
282
283
284bool KateTemplateHandler::operator() ( KKey key )
285{
286 if ( key==TQt::Key_Tab )
287 {
288 m_currentTabStop++;
289
290 if ( m_currentTabStop >= ( int ) m_tabOrder.count() )
291 m_currentTabStop = 0;
292 }
293 else
294 {
295 m_currentTabStop--;
296
297 if ( m_currentTabStop < 0 ) m_currentTabStop = m_tabOrder.count() - 1;
298 }
299
300 m_currentRange = m_tabOrder.at( m_currentTabStop ) ->ranges.at( 0 );
301
302 if ( m_tabOrder.at( m_currentTabStop ) ->isInitialValue )
303 {
304 m_doc->activeView()->setSelection( m_currentRange->start(), m_currentRange->end() );
305 }
306 else m_doc->activeView()->setSelection( m_currentRange->end(), m_currentRange->end() );
307
308 m_doc->activeView() ->setCursorPositionReal( m_currentRange->end().line(), m_currentRange->end().col() );
309 m_doc->activeView() ->tagLine( m_currentRange->end() );
310
311 return true;
312}
313
314void KateTemplateHandler::slotAboutToRemoveText( const KateTextRange &range )
315{
316 if ( m_recursion ) return ;
317
318 if ( m_currentRange && ( !m_currentRange->includes( range.start() ) ) ) locateRange( range.start() );
319
320 if ( m_currentRange != 0 )
321 {
322 if ( m_currentRange->end() <= range.end() ) return ;
323 }
324
325 if ( m_doc )
326 {
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() ) );
330 }
331
332 deleteLater();
333}
334
335void KateTemplateHandler::slotTextRemoved()
336{
337 if ( m_recursion ) return ;
338 if ( !m_currentRange ) return ;
339
340 slotTextInserted( m_currentRange->start().line(), m_currentRange->start().col() );
341}
342
KKey
KateArbitraryHighlight
An arbitrary highlighting interface for Kate.
Definition: katearbitraryhighlight.h:61
KateTextCursor
Simple cursor class with no document pointer.
Definition: katecursor.h:34
TDEStdAccel::end
const TDEShortcut & end()

kate

Skip menu "kate"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kate

Skip menu "kate"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for kate by doxygen 1.9.4
This website is maintained by Timothy Pearson.