KTextEditor
templateinterface.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2004, 2010 Joseph Wenninger <jowenn@kde.org> 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 version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "templateinterface.h" 00020 #include "document.h" 00021 #include "view.h" 00022 #include <QtCore/QString> 00023 #include <klocale.h> 00024 #include <kglobal.h> 00025 #include <QtCore/QDate> 00026 #include <QtCore/QRegExp> 00027 #include <kmessagebox.h> 00028 #include <kcalendarsystem.h> 00029 #include <unistd.h> 00030 #include <klibrary.h> 00031 00032 #include <kdebug.h> 00033 00034 #define DUMMY_VALUE "!KTE:TEMPLATEHANDLER_DUMMY_VALUE!" 00035 00036 using namespace KTextEditor; 00037 00038 bool TemplateInterface::expandMacros( QMap<QString, QString> &map, QWidget *parentWindow) 00039 { 00040 QDateTime datetime = QDateTime::currentDateTime(); 00041 QDate date = datetime.date(); 00042 QTime time = datetime.time(); 00043 typedef QString (*kabcbridgecalltype)(const QString&,QWidget *,bool *ok); 00044 kabcbridgecalltype kabcbridgecall=0; 00045 00046 QStringList kabcitems; 00047 kabcitems<<"firstname"<<"lastname"<<"fullname"<<"email"; 00048 00049 QMap<QString,QString>::Iterator it; 00050 for ( it = map.begin(); it != map.end(); ++it ) 00051 { 00052 QString placeholder = it.key(); 00053 if ( map[ placeholder ].isEmpty() ) 00054 { 00055 if ( placeholder == "index" ) map[ placeholder ] = "i"; 00056 else if ( placeholder == "loginname" ) 00057 {} 00058 else if (kabcitems.contains(placeholder)) 00059 { 00060 if (kabcbridgecall==0) 00061 { 00062 KLibrary lib(QLatin1String("ktexteditorkabcbridge")); 00063 kabcbridgecall=(kabcbridgecalltype)lib.resolveFunction("ktexteditorkabcbridge"); 00064 if (kabcbridgecall == 0) 00065 { 00066 KMessageBox::sorry(parentWindow,i18n("The template needs information about you, which is stored in your address book.\nHowever, the required plugin could not be loaded.\n\nPlease install the KDEPIM/Kontact package for your system.")); 00067 return false; 00068 } 00069 } 00070 bool ok; 00071 map[ placeholder ] = kabcbridgecall(placeholder,parentWindow,&ok); 00072 if (!ok) 00073 { 00074 return false; 00075 } 00076 } 00077 else if ( placeholder == "date" ) 00078 { 00079 map[ placeholder ] = KGlobal::locale() ->formatDate( date, KLocale::ShortDate ); 00080 } 00081 else if ( placeholder == "time" ) 00082 { 00083 map[ placeholder ] = KGlobal::locale() ->formatTime( time, true, false ); 00084 } 00085 else if ( placeholder == "year" ) 00086 { 00087 map[ placeholder ] = KGlobal::locale() ->calendar() ->yearString( date, KCalendarSystem::LongFormat ); 00088 } 00089 else if ( placeholder == "month" ) 00090 { 00091 map[ placeholder ] = QString::number( KGlobal::locale() ->calendar() ->month( date ) ); 00092 } 00093 else if ( placeholder == "day" ) 00094 { 00095 map[ placeholder ] = QString::number( KGlobal::locale() ->calendar() ->day( date ) ); 00096 } 00097 else if ( placeholder == "hostname" ) 00098 { 00099 char hostname[ 256 ]; 00100 hostname[ 0 ] = 0; 00101 gethostname( hostname, 255 ); 00102 hostname[ 255 ] = 0; 00103 map[ placeholder ] = QString::fromLocal8Bit( hostname ); 00104 } 00105 else if ( placeholder == "cursor" ) 00106 { 00107 map[ placeholder ] = '|'; 00108 } 00109 else if (placeholder== "selection" ) { 00110 //DO NOTHING, THE IMPLEMENTATION WILL HANDLE THIS 00111 } 00112 else map[ placeholder ] = placeholder; 00113 } 00114 } 00115 return true; 00116 } 00117 00118 bool TemplateInterface::KTE_INTERNAL_setupIntialValues(const QString& templateString,QMap<QString,QString> *initialValues) 00119 { 00120 QMap<QString, QString> enhancedInitValues( *initialValues ); 00121 00122 QRegExp rx( "[$%]\\{([^}\\r\\n]+)\\}" ); 00123 rx.setMinimal( true ); 00124 int pos = 0; 00125 int offset; 00126 QString initValue; 00127 while ( pos >= 0 ) 00128 { 00129 bool initValue_specified=false; 00130 pos = rx.indexIn( templateString, pos ); 00131 00132 if ( pos > -1 ) 00133 { 00134 offset = 0; 00135 while ( pos - offset > 0 && templateString[ pos - offset - 1 ] == '\\' ) { 00136 ++offset; 00137 } 00138 if ( offset % 2 == 1 ) { 00139 // match is escaped 00140 ++pos; 00141 continue; 00142 } 00143 QString placeholder = rx.cap( 1 ); 00144 00145 int pos_colon=placeholder.indexOf(":"); 00146 int pos_slash=placeholder.indexOf("/"); 00147 int pos_backtick=placeholder.indexOf("`"); 00148 bool check_slash=false; 00149 bool check_colon=false; 00150 bool check_backtick=false; 00151 if ((pos_colon==-1) && ( pos_slash==-1)) { 00152 //do nothing 00153 } else if ( (pos_colon==-1) && (pos_slash!=-1)) { 00154 check_slash=true; 00155 } else if ( (pos_colon!=-1) && (pos_slash==-1)) { 00156 check_colon=true; 00157 } else { 00158 if (pos_colon<pos_slash) 00159 check_colon=true; 00160 else 00161 check_slash=true; 00162 } 00163 00164 if ( (!check_slash) && (!check_colon) && (pos_backtick>=0) ) 00165 check_backtick=true; 00166 00167 if (check_slash) { 00168 //in most cases it should not matter, but better safe then sorry. 00169 const int end=placeholder.length(); 00170 int slashcount=0; 00171 int backslashcount=0; 00172 for (int i=0;i<end;i++) { 00173 if (placeholder[i]=='/') { 00174 if ((backslashcount%2)==0) slashcount++; 00175 if (slashcount==3) break; 00176 backslashcount=0; 00177 } else if (placeholder[i]=='\\') 00178 backslashcount++; 00179 else 00180 backslashcount=0; //any character terminates a backslash sequence 00181 } 00182 if (slashcount!=3) { 00183 const int tmpStrLength=templateString.length(); 00184 for (int i=pos+rx.matchedLength();(slashcount<3) && (i<tmpStrLength);i++,pos++) { 00185 if (templateString[i]=='/') { 00186 if ((backslashcount%2)==0) slashcount++; 00187 backslashcount=0; 00188 } else if (placeholder[i]=='\\') 00189 backslashcount++; 00190 else 00191 backslashcount=0; //any character terminates a backslash sequence 00192 } 00193 } 00194 //this is needed 00195 placeholder=placeholder.left(placeholder.indexOf("/")); 00196 } else if (check_colon) { 00197 initValue=placeholder.mid(pos_colon+1); 00198 initValue_specified=true; 00199 int backslashcount=0; 00200 for (int i=initValue.length()-1;(i>=0) && (initValue[i]=='\\'); i--) { 00201 backslashcount++; 00202 } 00203 initValue=initValue.left(initValue.length()-((backslashcount+1)/2)); 00204 if ((backslashcount % 2) ==1) { 00205 initValue+="}"; 00206 const int tmpStrLength=templateString.length(); 00207 backslashcount=0; 00208 for (int i=pos+rx.matchedLength();(i<tmpStrLength);i++,pos++) { 00209 if (templateString[i]=='}') { 00210 initValue=initValue.left(initValue.length()-((backslashcount+1)/2)); 00211 if ((backslashcount%2)==0) break; 00212 backslashcount=0; 00213 } else if (placeholder[i]=='\\') 00214 backslashcount++; 00215 else 00216 backslashcount=0; //any character terminates a backslash sequence 00217 initValue+=placeholder[i]; 00218 } 00219 } 00220 placeholder=placeholder.left(placeholder.indexOf(":")); 00221 } else if (check_backtick) { 00222 placeholder=placeholder.left(pos_backtick); 00223 } 00224 00225 if (placeholder.contains("@")) placeholder=placeholder.left(placeholder.indexOf("@")); 00226 if ( (! enhancedInitValues.contains( placeholder )) || (enhancedInitValues[placeholder]==DUMMY_VALUE) ) { 00227 if (initValue_specified) { 00228 enhancedInitValues[placeholder]=initValue; 00229 } else { 00230 enhancedInitValues[ placeholder ] = DUMMY_VALUE; 00231 } 00232 } 00233 pos += rx.matchedLength(); 00234 } 00235 } 00236 00237 kDebug()<<"-----------------------------------"; 00238 for (QMap<QString,QString>::iterator it=enhancedInitValues.begin();it!=enhancedInitValues.end();++it) { 00239 kDebug()<<"key:"<<it.key()<<" init value:"<<it.value(); 00240 if (it.value()==DUMMY_VALUE) it.value()=""; 00241 } 00242 kDebug()<<"-----------------------------------"; 00243 if (!expandMacros( enhancedInitValues, dynamic_cast<QWidget*>(this) ) ) return false; 00244 *initialValues=enhancedInitValues; 00245 return true; 00246 } 00247 00248 bool TemplateInterface::insertTemplateText ( const Cursor& insertPosition, const QString &templateString, const QMap<QString, QString> &initialValues) { 00249 QMap<QString,QString> enhancedInitValues(initialValues); 00250 if (!KTE_INTERNAL_setupIntialValues(templateString,&enhancedInitValues)) return false; 00251 return insertTemplateTextImplementation( insertPosition, templateString, enhancedInitValues); 00252 } 00253 00254 // kate: space-indent on; indent-width 2; replace-tabs on;
KDE 4.6 API Reference