From 7cbc12ee045564996052f315a2cef1b601208266 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Tue, 23 May 2023 00:46:25 +0300 Subject: [PATCH] interfaces: simplify templates handling and implement loginname Signed-off-by: Ivailo Monev --- interfaces/ktexteditor/templateinterface.cpp | 232 ++++--------------- interfaces/ktexteditor/templateinterface.h | 48 +--- 2 files changed, 51 insertions(+), 229 deletions(-) diff --git a/interfaces/ktexteditor/templateinterface.cpp b/interfaces/ktexteditor/templateinterface.cpp index a552957e..989a46d2 100644 --- a/interfaces/ktexteditor/templateinterface.cpp +++ b/interfaces/ktexteditor/templateinterface.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -36,204 +37,65 @@ using namespace KTextEditor; -bool TemplateInterface::expandMacros( QMap &map, QWidget *parentWindow) +bool TemplateInterface::insertTemplateText(const Cursor& insertPosition, const QString &templateString, const QMap &initialValues) { + // NOTE: THE IMPLEMENTATION WILL HANDLE cursor AND selection + QDateTime datetime = QDateTime::currentDateTime(); QDate date = datetime.date(); QTime time = datetime.time(); + QWidget *parentWindow = dynamic_cast(this); - QMap::Iterator it; - for ( it = map.begin(); it != map.end(); ++it ) - { - QString placeholder = it.key(); - if ( map[ placeholder ].isEmpty() ) - { - if ( placeholder == "index" ) map[ placeholder ] = "i"; - else if ( placeholder == "loginname" ) - {} - else if (placeholder == "fullname" || placeholder == "email") - { - KEMailSettings mailsettings; - const QString fullname = mailsettings.getSetting(KEMailSettings::RealName); - const QString email = mailsettings.getSetting(KEMailSettings::EmailAddress); - if (fullname.isEmpty() || email.isEmpty()) { - KMessageBox::sorry(parentWindow,i18n("The template needs information about you but it is not available.\n The information can be set set from system settings.")); - return false; - } - map[ "fullname" ] = fullname; - map[ "email" ] = email; - } - else if ( placeholder == "date" ) - { - map[ placeholder ] = KGlobal::locale() ->formatDate( date, KLocale::ShortDate ); - } - else if ( placeholder == "time" ) - { - map[ placeholder ] = KGlobal::locale() ->formatTime( time, true, false ); - } - else if ( placeholder == "year" ) - { - map[ placeholder ] = KGlobal::locale() ->calendar() ->formatDate(date, KLocale::Year, KLocale::LongNumber); - } - else if ( placeholder == "month" ) - { - map[ placeholder ] = QString::number( KGlobal::locale() ->calendar() ->month( date ) ); - } - else if ( placeholder == "day" ) - { - map[ placeholder ] = QString::number( KGlobal::locale() ->calendar() ->day( date ) ); - } - else if ( placeholder == "hostname" ) - { - map[ placeholder ] = QHostInfo::localHostName(); - } - else if ( placeholder == "cursor" ) - { - map[ placeholder ] = '|'; - } - else if (placeholder== "selection" ) { - //DO NOTHING, THE IMPLEMENTATION WILL HANDLE THIS - } - else map[ placeholder ] = placeholder; + QMap enhancedInitValues(initialValues); + if (templateString.contains(QLatin1String("%{loginname}"))) { + enhancedInitValues["loginname"] = KUser().loginName(); + } + + if (templateString.contains(QLatin1String("%{fullname}"))) { + KEMailSettings mailsettings; + const QString fullname = mailsettings.getSetting(KEMailSettings::RealName); + if (fullname.isEmpty()) { + KMessageBox::sorry(parentWindow,i18n("The template needs information about you but it is not available.\n The information can be set set from system settings.")); + return false; } + enhancedInitValues["fullname"] = fullname; } - return true; -} -bool TemplateInterface::KTE_INTERNAL_setupIntialValues(const QString& templateString,QMap *initialValues) -{ - QMap enhancedInitValues( *initialValues ); - - QRegExp rx( "[$%]\\{([^}\\r\\n]+)\\}" ); - rx.setMinimal( true ); - int pos = 0; - int offset; - QString initValue; - while ( pos >= 0 ) - { - bool initValue_specified=false; - pos = rx.indexIn( templateString, pos ); - - if ( pos > -1 ) - { - offset = 0; - while ( pos - offset > 0 && templateString[ pos - offset - 1 ] == '\\' ) { - ++offset; - } - if ( offset % 2 == 1 ) { - // match is escaped - ++pos; - continue; - } - QString placeholder = rx.cap( 1 ); - - int pos_colon=placeholder.indexOf(":"); - int pos_slash=placeholder.indexOf("/"); - int pos_backtick=placeholder.indexOf("`"); - bool check_slash=false; - bool check_colon=false; - bool check_backtick=false; - if ((pos_colon==-1) && ( pos_slash==-1)) { - //do nothing - } else if ( (pos_colon==-1) && (pos_slash!=-1)) { - check_slash=true; - } else if ( (pos_colon!=-1) && (pos_slash==-1)) { - check_colon=true; - } else { - if (pos_colon=0) ) - check_backtick=true; - - if (check_slash) { - //in most cases it should not matter, but better safe then sorry. - const int end=placeholder.length(); - int slashcount=0; - int backslashcount=0; - for (int i=0;i=0) && (initValue[i]=='\\'); i--) { - backslashcount++; - } - initValue=initValue.left(initValue.length()-((backslashcount+1)/2)); - if ((backslashcount % 2) ==1) { - initValue+="}"; - const int tmpStrLength=templateString.length(); - backslashcount=0; - for (int i=pos+rx.matchedLength();(i::iterator it=enhancedInitValues.begin();it!=enhancedInitValues.end();++it) { - kDebug()<<"key:"<formatDate(date, KLocale::ShortDate); } - kDebug()<<"-----------------------------------"; - if (!expandMacros( enhancedInitValues, dynamic_cast(this) ) ) return false; - *initialValues=enhancedInitValues; - return true; -} -bool TemplateInterface::insertTemplateText ( const Cursor& insertPosition, const QString &templateString, const QMap &initialValues) { - QMap enhancedInitValues(initialValues); - if (!KTE_INTERNAL_setupIntialValues(templateString,&enhancedInitValues)) return false; - return insertTemplateTextImplementation( insertPosition, templateString, enhancedInitValues); + if (templateString.contains(QLatin1String("%{time}"))) { + enhancedInitValues["time"] = KGlobal::locale()->formatTime(time, true, false); + } + + if (templateString.contains(QLatin1String("%{year}"))) { + enhancedInitValues["year"] = KGlobal::locale()->calendar()->formatDate(date, KLocale::Year, KLocale::LongNumber); + } + + if (templateString.contains(QLatin1String("%{month}"))) { + enhancedInitValues["month"] = QString::number(KGlobal::locale()->calendar()->month(date)); + } + + if (templateString.contains(QLatin1String("%{day}"))) { + enhancedInitValues["day"] = QString::number(KGlobal::locale()->calendar()->day(date)); + } + + if (templateString.contains(QLatin1String("%{hostname}"))) { + enhancedInitValues["hostname"] = QHostInfo::localHostName(); + } + + return insertTemplateTextImplementation(insertPosition, templateString, enhancedInitValues); } // kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/interfaces/ktexteditor/templateinterface.h b/interfaces/ktexteditor/templateinterface.h index cb23177f..891754a4 100644 --- a/interfaces/ktexteditor/templateinterface.h +++ b/interfaces/ktexteditor/templateinterface.h @@ -42,54 +42,26 @@ class KTEXTEDITOR_EXPORT TemplateInterface //should be named AbstractTemplateInt TemplateInterface(); virtual ~TemplateInterface(); - /** - * Parses \p templateString for macros in the form [$%]{NAME} and finds - * the value corresponding to NAME if any. The NAME string may contain - * any non-whitespace character execpt '}' - * \param initialValues a map with the keys for the macros to expand. - * keys with a value are ignored. - * \param parentWindow is used if dialogs have to be shown - * \return true if all macros was successfully expanded - * \see insertTemplateText for a list of supported macros - */ - static bool expandMacros( QMap &initialValues, QWidget *parentWindow ); - public: /** - * Inserts an interactive ediable template text at line "line", column "col". + * Inserts an interactive ediable template text at cursor position @p insertPosition. * \return true if inserting the string succeeded * * Use insertTemplateText(lines(), ...) to append text at end of document * Template strings look like - * "for( int ${index}=0;${index}<10;${index}++) { ${cursor} };" + * "for( int i=0;i<10;i++) { %{cursor} };" * or "%{date}" * * This syntax is somewhat similar to the one found in the Eclipse editor or textmate. * * There are certain common placeholders (macros), which get assigned a - * default initialValue, If the second parameter does not a given value. - * For all others the initial value is the name of the placeholder. + * default initialValue. * * Placeholder names may only consist of a-zA-Z0-9_ * - * @since 4.5 - * if a placeholder is a mirror, the place holder name may contain additional information - * ${something/regexp/replacement/} takes the value of the placeholder something and replaces the match with the replacement before inserting the mirrored value - * ${something/regexp/replacement/g} like above, but for all occurences - * The syntax of the regexp and the replacement are the ones from kateparts regexp search/replace - * ${something/regexp/replacement/i} like above, but case insensitive - * The syntax of the regexp and the replacement are the ones from kateparts regexp search/replace - * Possible flags: g and i. Those flags can be combined too - * If a literal / should appear in the regexp, it has to be escaped \/, - * literal \ has to be escaped too - * - * If you have mirrored ranges and want another occurence than the first one as the master - * you can add @ directly after the placeholder name. - * * Common placeholders and values are * - * - index: "i" * - loginname: The current users's loginname * - fullname: The current user's first and last name retrieved from kabc * - email: The current user's primary email address retrieved from kabc @@ -100,13 +72,7 @@ class KTEXTEDITOR_EXPORT TemplateInterface //should be named AbstractTemplateInt * - day: current day * - hostname: hostname of the computer * - selection: The implementation should set this to the selected text, if any - * - cursor: at this position the cursor will be after editing of the - * template has finished, this has to be taken care of by the actual - * implementation. The placeholder gets a value of "|" assigned. - * - * If a macro is started with a % (persent sign) like "%{date}" it isn't added - * to the list editable strings ( for example TAB key navigation) if a value - * differing from the macro name is found. + * - cursor: The implementation should set the cursor position there, if any. * * If the editor supports some kind of smart indentation, the inserted code * should be layouted by the indenter. @@ -122,12 +88,6 @@ protected: * \return true if any text was inserted. */ virtual bool insertTemplateTextImplementation ( const Cursor &insertPosition, const QString &templateString, const QMap &initialValues)=0; - - /** - * DO NOT USE !!!! THIS IS USED INTERNALLY by the interface only !!!!!! - * Behaviour might change !!!!!!! - */ - bool KTE_INTERNAL_setupIntialValues(const QString &templateString, QMap *initialValues); }; }