• 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 
28 KateTemplateHandler::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, TQT_SIGNAL( destroyed() ), this, TQT_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,TQT_SIGNAL(charactersInteractivelyInserted(int ,int ,const TQString&)),this,
120  TQT_SLOT(slotCharactersInteractivlyInserted(int,int,const TQString&)));
121  connect(doc,TQT_SIGNAL(charactersSemiInteractivelyInserted(int ,int ,const TQString&)),this,
122  TQT_SLOT(slotCharactersInteractivlyInserted(int,int,const TQString&)));*/
123  connect( doc, TQT_SIGNAL( textInserted( int, int ) ), this, TQT_SLOT( slotTextInserted( int, int ) ) );
124  connect( doc, TQT_SIGNAL( aboutToRemoveText( const KateTextRange& ) ), this, TQT_SLOT( slotAboutToRemoveText( const KateTextRange& ) ) );
125  connect( doc, TQT_SIGNAL( textRemoved() ), this, TQT_SLOT( slotTextRemoved() ) );
126 
127  ( *this ) ( Qt::Key_Tab );
128 }
129 
130 KateTemplateHandler::~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 
147 void KateTemplateHandler::slotDocumentDestroyed() {m_doc = 0;}
148 
149 void 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 
202 void 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 
251 void 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 
284 bool KateTemplateHandler::operator() ( KKey key )
285 {
286  if ( key==Qt::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 
314 void 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, TQT_SIGNAL( textInserted( int, int ) ), this, TQT_SLOT( slotTextInserted( int, int ) ) );
328  disconnect( m_doc, TQT_SIGNAL( aboutToRemoveText( const KateTextRange& ) ), this, TQT_SLOT( slotAboutToRemoveText( const KateTextRange& ) ) );
329  disconnect( m_doc, TQT_SIGNAL( textRemoved() ), this, TQT_SLOT( slotTextRemoved() ) );
330  }
331 
332  deleteLater();
333 }
334 
335 void 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 
KateTextCursor
Simple cursor class with no document pointer.
Definition: katecursor.h:33
TDEStdAccel::end
const TDEShortcut & end()
KKey
KateArbitraryHighlight
An arbitrary highlighting interface for Kate.
Definition: katearbitraryhighlight.h:60

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for kate by doxygen 1.8.8
This website is maintained by Timothy Pearson.