• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KIO

  • sources
  • kde-4.14
  • kdelibs
  • kio
  • kio
kshellcompletion.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries
2  Copyright (C) 2000 David Smith <dsmith@algonet.se>
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 as published by the Free Software Foundation; either
7  version 2 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "kshellcompletion.h"
21 
22 #include <stdlib.h>
23 #include <kdebug.h>
24 #include <QtCore/QCharRef>
25 #include <QtCore/QMutableStringListIterator>
26 #include <QtCore/QRegExp>
27 #include <kcompletion.h>
28 
29 class KShellCompletionPrivate
30 {
31 public:
32  KShellCompletionPrivate()
33  : m_word_break_char(' ')
34  , m_quote_char1( '\"' )
35  , m_quote_char2( '\'' )
36  , m_escape_char( '\\' )
37  {
38  }
39 
40  void splitText(const QString &text, QString &text_start, QString &text_compl) const;
41  bool quoteText(QString *text, bool force, bool skip_last) const;
42  QString unquote(const QString &text) const;
43 
44  QString m_text_start; // part of the text that was not completed
45  QString m_text_compl; // part of the text that was completed (unchanged)
46 
47  QChar m_word_break_char;
48  QChar m_quote_char1;
49  QChar m_quote_char2;
50  QChar m_escape_char;
51 };
52 
53 KShellCompletion::KShellCompletion()
54  : KUrlCompletion(),
55  d( new KShellCompletionPrivate )
56 {
57 }
58 
59 KShellCompletion::~KShellCompletion()
60 {
61  delete d;
62 }
63 
64 
65 /*
66  * makeCompletion()
67  *
68  * Entry point for file name completion
69  */
70 QString KShellCompletion::makeCompletion(const QString &text)
71 {
72  // Split text at the last unquoted space
73  //
74  d->splitText(text, d->m_text_start, d->m_text_compl);
75 
76  // Remove quotes from the text to be completed
77  //
78  QString tmp = d->unquote(d->m_text_compl);
79  d->m_text_compl = tmp;
80 
81  // Do exe-completion if there was no unquoted space
82  //
83  bool is_exe_completion = true;
84 
85  for ( int i = 0; i < d->m_text_start.length(); i++ ) {
86  if ( d->m_text_start[i] != d->m_word_break_char ) {
87  is_exe_completion = false;
88  break;
89  }
90  }
91 
92  Mode mode = (is_exe_completion ? ExeCompletion : FileCompletion );
93 
94  setMode(mode);
95 
96  // Make completion on the last part of text
97  //
98  return KUrlCompletion::makeCompletion( d->m_text_compl );
99 }
100 
101 /*
102  * postProcessMatch, postProcessMatches
103  *
104  * Called by KCompletion before emitting match() and matches()
105  *
106  * Add add the part of the text that was not completed
107  * Add quotes when needed
108  */
109 void KShellCompletion::postProcessMatch( QString *match ) const
110 {
111  KUrlCompletion::postProcessMatch( match );
112 
113  if ( match->isNull() )
114  return;
115 
116  if ( match->endsWith( QLatin1Char( '/' ) ) )
117  d->quoteText( match, false, true ); // don't quote the trailing '/'
118  else
119  d->quoteText( match, false, false ); // quote the whole text
120 
121  match->prepend( d->m_text_start );
122 }
123 
124 void KShellCompletion::postProcessMatches( QStringList *matches ) const
125 {
126  KUrlCompletion::postProcessMatches( matches );
127 
128  for ( QStringList::Iterator it = matches->begin();
129  it != matches->end(); ++it )
130  {
131  if ( !(*it).isNull() ) {
132  if ( (*it).endsWith( QLatin1Char( '/' ) ) )
133  d->quoteText( &(*it), false, true ); // don't quote trailing '/'
134  else
135  d->quoteText( &(*it), false, false ); // quote the whole text
136 
137  (*it).prepend( d->m_text_start );
138  }
139  }
140 }
141 
142 void KShellCompletion::postProcessMatches( KCompletionMatches *matches ) const
143 {
144  KUrlCompletion::postProcessMatches( matches );
145 
146  for ( KCompletionMatches::Iterator it = matches->begin();
147  it != matches->end(); ++it )
148  {
149  if ( !(*it).value().isNull() ) {
150  if ( (*it).value().endsWith( QLatin1Char( '/' ) ) )
151  d->quoteText( &(*it).value(), false, true ); // don't quote trailing '/'
152  else
153  d->quoteText( &(*it).value(), false, false ); // quote the whole text
154 
155  (*it).value().prepend( d->m_text_start );
156  }
157  }
158 }
159 
160 /*
161  * splitText
162  *
163  * Split text at the last unquoted space
164  *
165  * text_start = [out] text at the left, including the space
166  * text_compl = [out] text at the right
167  */
168 void KShellCompletionPrivate::splitText(const QString &text, QString &text_start,
169  QString &text_compl) const
170 {
171  bool in_quote = false;
172  bool escaped = false;
173  QChar p_last_quote_char;
174  int last_unquoted_space = -1;
175  int end_space_len = 0;
176 
177  for (int pos = 0; pos < text.length(); pos++) {
178 
179  end_space_len = 0;
180 
181  if ( escaped ) {
182  escaped = false;
183  }
184  else if ( in_quote && text[pos] == p_last_quote_char ) {
185  in_quote = false;
186  }
187  else if ( !in_quote && text[pos] == m_quote_char1 ) {
188  p_last_quote_char = m_quote_char1;
189  in_quote = true;
190  }
191  else if ( !in_quote && text[pos] == m_quote_char2 ) {
192  p_last_quote_char = m_quote_char2;
193  in_quote = true;
194  }
195  else if ( text[pos] == m_escape_char ) {
196  escaped = true;
197  }
198  else if ( !in_quote && text[pos] == m_word_break_char ) {
199 
200  end_space_len = 1;
201 
202  while ( pos+1 < text.length() && text[pos+1] == m_word_break_char ) {
203  end_space_len++;
204  pos++;
205  }
206 
207  if ( pos+1 == text.length() )
208  break;
209 
210  last_unquoted_space = pos;
211  }
212  }
213 
214  text_start = text.left( last_unquoted_space + 1 );
215 
216  // the last part without trailing blanks
217  text_compl = text.mid( last_unquoted_space + 1 );
218 }
219 
220 /*
221  * quoteText()
222  *
223  * Add quotations to 'text' if needed or if 'force' = true
224  * Returns true if quotes were added
225  *
226  * skip_last => ignore the last charachter (we add a space or '/' to all filenames)
227  */
228 bool KShellCompletionPrivate::quoteText(QString *text, bool force, bool skip_last) const
229 {
230  int pos = 0;
231 
232  if ( !force ) {
233  pos = text->indexOf( m_word_break_char );
234  if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1;
235  }
236 
237  if ( !force && pos == -1 ) {
238  pos = text->indexOf( m_quote_char1 );
239  if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1;
240  }
241 
242  if ( !force && pos == -1 ) {
243  pos = text->indexOf( m_quote_char2 );
244  if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1;
245  }
246 
247  if ( !force && pos == -1 ) {
248  pos = text->indexOf( m_escape_char );
249  if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1;
250  }
251 
252  if ( force || (pos >= 0) ) {
253 
254  // Escape \ in the string
255  text->replace( m_escape_char,
256  QString( m_escape_char ) + m_escape_char );
257 
258  // Escape " in the string
259  text->replace( m_quote_char1,
260  QString( m_escape_char ) + m_quote_char1 );
261 
262  // " at the beginning
263  text->insert( 0, m_quote_char1 );
264 
265  // " at the end
266  if ( skip_last )
267  text->insert( text->length()-1, m_quote_char1 );
268  else
269  text->insert( text->length(), m_quote_char1 );
270 
271  return true;
272  }
273 
274  return false;
275 }
276 
277 /*
278  * unquote
279  *
280  * Remove quotes and return the result in a new string
281  *
282  */
283 QString KShellCompletionPrivate::unquote(const QString &text) const
284 {
285  bool in_quote = false;
286  bool escaped = false;
287  QChar p_last_quote_char;
288  QString result;
289 
290  for (int pos = 0; pos < text.length(); pos++) {
291 
292  if ( escaped ) {
293  escaped = false;
294  result.insert( result.length(), text[pos] );
295  }
296  else if ( in_quote && text[pos] == p_last_quote_char ) {
297  in_quote = false;
298  }
299  else if ( !in_quote && text[pos] == m_quote_char1 ) {
300  p_last_quote_char = m_quote_char1;
301  in_quote = true;
302  }
303  else if ( !in_quote && text[pos] == m_quote_char2 ) {
304  p_last_quote_char = m_quote_char2;
305  in_quote = true;
306  }
307  else if ( text[pos] == m_escape_char ) {
308  escaped = true;
309  result.insert( result.length(), text[pos] );
310  }
311  else {
312  result.insert( result.length(), text[pos] );
313  }
314 
315  }
316 
317  return result;
318 }
319 
320 #include "kshellcompletion.moc"
321 
KUrlCompletion::FileCompletion
Definition: kurlcompletion.h:53
KShellCompletion::~KShellCompletion
~KShellCompletion()
Definition: kshellcompletion.cpp:59
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
kshellcompletion.h
kdebug.h
KShellCompletion::postProcessMatch
void postProcessMatch(QString *match) const
Definition: kshellcompletion.cpp:109
KUrlCompletion::setMode
virtual void setMode(Mode mode)
Changes the completion mode: exe or file completion.
Definition: kurlcompletion.cpp:559
QChar
QString::prepend
QString & prepend(QChar ch)
KUrlCompletion::Mode
Mode
Determines how completion is done.
Definition: kurlcompletion.h:53
KUrlCompletion::mode
virtual Mode mode() const
Returns the completion mode: exe or file completion (default FileCompletion).
Definition: kurlcompletion.cpp:554
QString::isNull
bool isNull() const
KShellCompletion::KShellCompletion
KShellCompletion()
Constructs a KShellCompletion object.
Definition: kshellcompletion.cpp:53
QString::insert
QString & insert(int position, QChar ch)
KUrlCompletion::makeCompletion
virtual QString makeCompletion(const QString &text)
Finds completions to the given text.
Definition: kurlcompletion.cpp:589
KUrlCompletion::postProcessMatch
void postProcessMatch(QString *match) const
Definition: kurlcompletion.cpp:1268
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
QList::Iterator
typedef Iterator
QString
KCompletionMatches
QStringList
kcompletion.h
QList::end
iterator end()
QLatin1Char
QString::replace
QString & replace(int position, int n, QChar after)
QString::mid
QString mid(int position, int n) const
KUrlCompletion::ExeCompletion
Definition: kurlcompletion.h:53
QString::length
int length() const
QString::left
QString left(int n) const
KShellCompletion::postProcessMatches
void postProcessMatches(QStringList *matches) const
Definition: kshellcompletion.cpp:124
KUrlCompletion::postProcessMatches
void postProcessMatches(QStringList *matches) const
Definition: kurlcompletion.cpp:1317
KShellCompletion::makeCompletion
QString makeCompletion(const QString &text)
Finds completions to the given text.
Definition: kshellcompletion.cpp:70
QList::begin
iterator begin()
KUrlCompletion
This class does completion of URLs including user directories (~user) and environment variables...
Definition: kurlcompletion.h:41
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:24:53 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal