| # kio Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# kshellcompletion.cpp

    00001 /* This file is part of the KDE libraries
    00002     Copyright (C) 2000 David Smith <dsmith@algonet.se>
    00003
    00004     This library is free software; you can redistribute it and/or
    00005     modify it under the terms of the GNU Library General Public
    00006     License as published by the Free Software Foundation; either
    00007     version 2 of the License, or (at your option) any later version.
    00008
    00009     This library is distributed in the hope that it will be useful,
    00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012     Library General Public License for more details.
    00013
    00014     You should have received a copy of the GNU Library General Public License
    00015     along with this library; see the file COPYING.LIB.  If not, write to
    00016     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00017     Boston, MA 02111-1307, USA.
    00018 */
    00019
    00020 #include <stdlib.h>
    00021 #include <kdebug.h>
    00022 #include <qstring.h>
    00023 #include <qstringlist.h>
    00024 #include <qregexp.h>
    00025 #include <kcompletion.h>
    00026
    00027 #include "kshellcompletion.h"
    00028
    00029 class KShellCompletionPrivate
    00030 {
    00031 };
    00032
    00033 KShellCompletion::KShellCompletion() : KURLCompletion()
    00034 {
    00035         m_word_break_char = ' ';
    00036         m_quote_char1 = '\"';
    00037         m_quote_char2 = '\'';
    00038         m_escape_char = '\\';
    00039 }
    00040
    00041 /*
    00042  * makeCompletion()
    00043  *
    00044  * Entry point for file name completion
    00045  */
    00046 QString KShellCompletion::makeCompletion(const QString &text)
    00047 {
    00048         // Split text at the last unquoted space
    00049         //
    00050         splitText(text, m_text_start, m_text_compl);
    00051
    00052         // Remove quotes from the text to be completed
    00053         //
    00054         QString tmp = unquote(m_text_compl);
    00055         m_text_compl = tmp;
    00056
    00057         // Do exe-completion if there was no unquoted space
    00058         //
    00059         bool is_exe_completion = true;
    00060
    00061         for ( uint i = 0; i < m_text_start.length(); i++ ) {
    00062                 if ( m_text_start[i] != m_word_break_char ) {
    00063                         is_exe_completion = false;
    00064                         break;
    00065                 }
    00066         }
    00067
    00068         Mode mode = (is_exe_completion ? ExeCompletion : FileCompletion );
    00069
    00070         setMode(mode);
    00071
    00072         // Make completion on the last part of text
    00073         //
    00074         return KURLCompletion::makeCompletion( m_text_compl );
    00075 }
    00076
    00077 /*
    00078  * postProcessMatch, postProcessMatches
    00079  *
    00080  * Called by KCompletion before emitting match() and matches()
    00081  *
    00082  * Add add the part of the text that was not completed
    00083  * Add quotes when needed
    00084  */
    00085 void KShellCompletion::postProcessMatch( QString *match ) const
    00086 {
    00087         //kDebugInfo("KShellCompletion::postProcessMatch() in: '%s'",
    00088         //      match->latin1());
    00089
    00090         KURLCompletion::postProcessMatch( match );
    00091
    00092         if ( match->isNull() )
    00093                 return;
    00094
    00095         if ( match->right(1) == QChar('/') )
    00096                 quoteText( match, false, true ); // don't quote the trailing '/'
    00097         else
    00098                 quoteText( match, false, false ); // quote the whole text
    00099
    00100         match->prepend( m_text_start );
    00101
    00102         //kDebugInfo("KShellCompletion::postProcessMatch() ut: '%s'",
    00103         //      match->latin1());
    00104 }
    00105
    00106 void KShellCompletion::postProcessMatches( QStringList *matches ) const
    00107 {
    00108         KURLCompletion::postProcessMatches( matches );
    00109
    00110         for ( QStringList::Iterator it = matches->begin();
    00111                   it != matches->end(); it++ )
    00112         {
    00113                 if ( (*it) != QString::null ) {
    00114                         if ( (*it).right(1) == QChar('/') )
    00115                                 quoteText( &(*it), false, true ); // don't quote trailing '/'
    00116                         else
    00117                                 quoteText( &(*it), false, false ); // quote the whole text
    00118
    00119                         (*it).prepend( m_text_start );
    00120                 }
    00121         }
    00122 }
    00123
    00124 void KShellCompletion::postProcessMatches( KCompletionMatches *matches ) const
    00125 {
    00126         KURLCompletion::postProcessMatches( matches );
    00127
    00128         for ( KCompletionMatches::Iterator it = matches->begin();
    00129                   it != matches->end(); it++ )
    00130         {
    00131                 if ( (*it).value() != QString::null ) {
    00132                         if ( (*it).value().right(1) == QChar('/') )
    00133                                 quoteText( &(*it).value(), false, true ); // don't quote trailing '/'
    00134                         else
    00135                                 quoteText( &(*it).value(), false, false ); // quote the whole text
    00136
    00137                         (*it).value().prepend( m_text_start );
    00138                 }
    00139         }
    00140 }
    00141
    00142 /*
    00143  * splitText
    00144  *
    00145  * Split text at the last unquoted space
    00146  *
    00147  * text_start = [out] text at the left, including the space
    00148  * text_compl = [out] text at the right
    00149  */
    00150 void KShellCompletion::splitText(const QString &text, QString &text_start,
    00151                 QString &text_compl) const
    00152 {
    00153         bool in_quote = false;
    00154         bool escaped = false;
    00155         QChar p_last_quote_char;
    00156         int last_unquoted_space = -1;
    00157         int end_space_len = 0;
    00158
    00159         for (uint pos = 0; pos < text.length(); pos++) {
    00160
    00161                 end_space_len = 0;
    00162
    00163                 if ( escaped ) {
    00164                         escaped = false;
    00165                 }
    00166                 else if ( in_quote && text[pos] == p_last_quote_char ) {
    00167                         in_quote = false;
    00168                 }
    00169                 else if ( !in_quote && text[pos] == m_quote_char1 ) {
    00170                         p_last_quote_char = m_quote_char1;
    00171                         in_quote = true;
    00172                 }
    00173                 else if ( !in_quote && text[pos] == m_quote_char2 ) {
    00174                         p_last_quote_char = m_quote_char2;
    00175                         in_quote = true;
    00176                 }
    00177                 else if ( text[pos] == m_escape_char ) {
    00178                         escaped = true;
    00179                 }
    00180                 else if ( !in_quote && text[pos] == m_word_break_char ) {
    00181
    00182                         end_space_len = 1;
    00183
    00184                         while ( pos+1 < text.length() && text[pos+1] == m_word_break_char ) {
    00185                                 end_space_len++;
    00186                                 pos++;
    00187                         }
    00188
    00189                         if ( pos+1 == text.length() )
    00190                                 break;
    00191
    00192                         last_unquoted_space = pos;
    00193                 }
    00194         }
    00195
    00196         text_start = text.left( last_unquoted_space + 1 );
    00197
    00198         // the last part without trailing blanks
    00199         text_compl = text.mid( last_unquoted_space + 1 );
    00200
    00201 //      text_compl = text.mid( last_unquoted_space + 1,
    00202 //                                                 text.length() - end_space_len - (last_unquoted_space + 1) );
    00203
    00204         //kDebugInfo("split right = '%s'", text_compl.latin1());
    00205 }
    00206
    00207 /*
    00208  * quoteText()
    00209  *
    00210  * Add quotations to 'text' if needed or if 'force' = true
    00211  * Returns true if quotes were added
    00212  *
    00213  * skip_last => ignore the last charachter (we add a space or '/' to all filenames)
    00214  */
    00215 bool KShellCompletion::quoteText(QString *text, bool force, bool skip_last) const
    00216 {
    00217         int pos = 0;
    00218
    00219         if ( !force ) {
    00220                 pos = text->find( m_word_break_char );
    00221                 if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1;
    00222         }
    00223
    00224         if ( !force && pos == -1 ) {
    00225                 pos = text->find( m_quote_char1 );
    00226                 if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1;
    00227         }
    00228
    00229         if ( !force && pos == -1 ) {
    00230                 pos = text->find( m_quote_char2 );
    00231                 if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1;
    00232         }
    00233
    00234         if ( !force && pos == -1 ) {
    00235                 pos = text->find( m_escape_char );
    00236                 if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1;
    00237         }
    00238
    00239         if ( force || (pos >= 0) ) {
    00240
    00241                 // Escape \ in the string
    00242                 text->replace( QRegExp( m_escape_char ),
    00243                                QString( m_escape_char ) + m_escape_char );
    00244
    00245                 // Escape " in the string
    00246                 text->replace( QRegExp( m_quote_char1 ),
    00247                                QString( m_escape_char ) + m_quote_char1 );
    00248
    00249                 // " at the beginning
    00250                 text->insert( 0, m_quote_char1 );
    00251
    00252                 // " at the end
    00253                 if ( skip_last )
    00254                         text->insert( text->length()-1, m_quote_char1 );
    00255                 else
    00256                         text->insert( text->length(), m_quote_char1 );
    00257
    00258                 return true;
    00259         }
    00260
    00261         return false;
    00262 }
    00263
    00264 /*
    00265  * unquote
    00266  *
    00267  * Remove quotes and return the result in a new string
    00268  *
    00269  */
    00270 QString KShellCompletion::unquote(const QString &text) const
    00271 {
    00272         bool in_quote = false;
    00273         bool escaped = false;
    00274         QChar p_last_quote_char;
    00275         QString result;
    00276
    00277         for (uint pos = 0; pos < text.length(); pos++) {
    00278
    00279                 if ( escaped ) {
    00280                         escaped = false;
    00281                         result.insert( result.length(), text[pos] );
    00282                 }
    00283                 else if ( in_quote && text[pos] == p_last_quote_char ) {
    00284                         in_quote = false;
    00285                 }
    00286                 else if ( !in_quote && text[pos] == m_quote_char1 ) {
    00287                         p_last_quote_char = m_quote_char1;
    00288                         in_quote = true;
    00289                 }
    00290                 else if ( !in_quote && text[pos] == m_quote_char2 ) {
    00291                         p_last_quote_char = m_quote_char2;
    00292                         in_quote = true;
    00293                 }
    00294                 else if ( text[pos] == m_escape_char ) {
    00295                         escaped = true;
    00296                         result.insert( result.length(), text[pos] );
    00297                 }
    00298                 else {
    00299                         result.insert( result.length(), text[pos] );
    00300                 }
    00301
    00302         }
    00303
    00304         return result;
    00305 }
    00306
    00307 void KShellCompletion::virtual_hook( int id, void* data )
    00308 { KURLCompletion::virtual_hook( id, data ); }
    00309
    00310 #include "kshellcompletion.moc"
    00311

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:14:21 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001