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

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;

KTextEditor

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • 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
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal