mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 18:32:49 +00:00
interfaces: simplify templates handling and implement loginname
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
6e549c55ff
commit
7cbc12ee04
2 changed files with 51 additions and 229 deletions
|
@ -25,6 +25,7 @@
|
||||||
#include <kmessagebox.h>
|
#include <kmessagebox.h>
|
||||||
#include <kcalendarsystem.h>
|
#include <kcalendarsystem.h>
|
||||||
#include <kemailsettings.h>
|
#include <kemailsettings.h>
|
||||||
|
#include <kuser.h>
|
||||||
#include <kdebug.h>
|
#include <kdebug.h>
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
@ -36,204 +37,65 @@
|
||||||
|
|
||||||
using namespace KTextEditor;
|
using namespace KTextEditor;
|
||||||
|
|
||||||
bool TemplateInterface::expandMacros( QMap<QString, QString> &map, QWidget *parentWindow)
|
bool TemplateInterface::insertTemplateText(const Cursor& insertPosition, const QString &templateString, const QMap<QString, QString> &initialValues)
|
||||||
{
|
{
|
||||||
|
// NOTE: THE IMPLEMENTATION WILL HANDLE cursor AND selection
|
||||||
|
|
||||||
QDateTime datetime = QDateTime::currentDateTime();
|
QDateTime datetime = QDateTime::currentDateTime();
|
||||||
QDate date = datetime.date();
|
QDate date = datetime.date();
|
||||||
QTime time = datetime.time();
|
QTime time = datetime.time();
|
||||||
|
QWidget *parentWindow = dynamic_cast<QWidget*>(this);
|
||||||
|
|
||||||
QMap<QString,QString>::Iterator it;
|
QMap<QString, QString> enhancedInitValues(initialValues);
|
||||||
for ( it = map.begin(); it != map.end(); ++it )
|
if (templateString.contains(QLatin1String("%{loginname}"))) {
|
||||||
{
|
enhancedInitValues["loginname"] = KUser().loginName();
|
||||||
QString placeholder = it.key();
|
}
|
||||||
if ( map[ placeholder ].isEmpty() )
|
|
||||||
{
|
if (templateString.contains(QLatin1String("%{fullname}"))) {
|
||||||
if ( placeholder == "index" ) map[ placeholder ] = "i";
|
KEMailSettings mailsettings;
|
||||||
else if ( placeholder == "loginname" )
|
const QString fullname = mailsettings.getSetting(KEMailSettings::RealName);
|
||||||
{}
|
if (fullname.isEmpty()) {
|
||||||
else if (placeholder == "fullname" || placeholder == "email")
|
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;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
enhancedInitValues["fullname"] = fullname;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TemplateInterface::KTE_INTERNAL_setupIntialValues(const QString& templateString,QMap<QString,QString> *initialValues)
|
if (templateString.contains(QLatin1String("%{email}"))) {
|
||||||
{
|
KEMailSettings mailsettings;
|
||||||
QMap<QString, QString> enhancedInitValues( *initialValues );
|
const QString email = mailsettings.getSetting(KEMailSettings::EmailAddress);
|
||||||
|
if (email.isEmpty()) {
|
||||||
QRegExp rx( "[$%]\\{([^}\\r\\n]+)\\}" );
|
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."));
|
||||||
rx.setMinimal( true );
|
return false;
|
||||||
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<pos_slash)
|
|
||||||
check_colon=true;
|
|
||||||
else
|
|
||||||
check_slash=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (!check_slash) && (!check_colon) && (pos_backtick>=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<end;i++) {
|
|
||||||
if (placeholder[i]=='/') {
|
|
||||||
if ((backslashcount%2)==0) slashcount++;
|
|
||||||
if (slashcount==3) break;
|
|
||||||
backslashcount=0;
|
|
||||||
} else if (placeholder[i]=='\\')
|
|
||||||
backslashcount++;
|
|
||||||
else
|
|
||||||
backslashcount=0; //any character terminates a backslash sequence
|
|
||||||
}
|
|
||||||
if (slashcount!=3) {
|
|
||||||
const int tmpStrLength=templateString.length();
|
|
||||||
for (int i=pos+rx.matchedLength();(slashcount<3) && (i<tmpStrLength);i++,pos++) {
|
|
||||||
if (templateString[i]=='/') {
|
|
||||||
if ((backslashcount%2)==0) slashcount++;
|
|
||||||
backslashcount=0;
|
|
||||||
} else if (placeholder[i]=='\\')
|
|
||||||
backslashcount++;
|
|
||||||
else
|
|
||||||
backslashcount=0; //any character terminates a backslash sequence
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//this is needed
|
|
||||||
placeholder=placeholder.left(placeholder.indexOf("/"));
|
|
||||||
} else if (check_colon) {
|
|
||||||
initValue=placeholder.mid(pos_colon+1);
|
|
||||||
initValue_specified=true;
|
|
||||||
int backslashcount=0;
|
|
||||||
for (int i=initValue.length()-1;(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<tmpStrLength);i++,pos++) {
|
|
||||||
if (templateString[i]=='}') {
|
|
||||||
initValue=initValue.left(initValue.length()-((backslashcount+1)/2));
|
|
||||||
if ((backslashcount%2)==0) break;
|
|
||||||
backslashcount=0;
|
|
||||||
} else if (placeholder[i]=='\\')
|
|
||||||
backslashcount++;
|
|
||||||
else
|
|
||||||
backslashcount=0; //any character terminates a backslash sequence
|
|
||||||
initValue+=placeholder[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
placeholder=placeholder.left(placeholder.indexOf(":"));
|
|
||||||
} else if (check_backtick) {
|
|
||||||
placeholder=placeholder.left(pos_backtick);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (placeholder.contains("@")) placeholder=placeholder.left(placeholder.indexOf("@"));
|
|
||||||
if ( (! enhancedInitValues.contains( placeholder )) || (enhancedInitValues[placeholder]==DUMMY_VALUE) ) {
|
|
||||||
if (initValue_specified) {
|
|
||||||
enhancedInitValues[placeholder]=initValue;
|
|
||||||
} else {
|
|
||||||
enhancedInitValues[ placeholder ] = DUMMY_VALUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pos += rx.matchedLength();
|
|
||||||
}
|
}
|
||||||
|
enhancedInitValues["email"] = email;
|
||||||
}
|
}
|
||||||
|
|
||||||
kDebug()<<"-----------------------------------";
|
if (templateString.contains(QLatin1String("%{date}"))) {
|
||||||
for (QMap<QString,QString>::iterator it=enhancedInitValues.begin();it!=enhancedInitValues.end();++it) {
|
enhancedInitValues["date"] = KGlobal::locale()->formatDate(date, KLocale::ShortDate);
|
||||||
kDebug()<<"key:"<<it.key()<<" init value:"<<it.value();
|
|
||||||
if (it.value()==DUMMY_VALUE) it.value()="";
|
|
||||||
}
|
}
|
||||||
kDebug()<<"-----------------------------------";
|
|
||||||
if (!expandMacros( enhancedInitValues, dynamic_cast<QWidget*>(this) ) ) return false;
|
|
||||||
*initialValues=enhancedInitValues;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TemplateInterface::insertTemplateText ( const Cursor& insertPosition, const QString &templateString, const QMap<QString, QString> &initialValues) {
|
if (templateString.contains(QLatin1String("%{time}"))) {
|
||||||
QMap<QString,QString> enhancedInitValues(initialValues);
|
enhancedInitValues["time"] = KGlobal::locale()->formatTime(time, true, false);
|
||||||
if (!KTE_INTERNAL_setupIntialValues(templateString,&enhancedInitValues)) return false;
|
}
|
||||||
return insertTemplateTextImplementation( insertPosition, templateString, enhancedInitValues);
|
|
||||||
|
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;
|
// kate: space-indent on; indent-width 2; replace-tabs on;
|
||||||
|
|
|
@ -42,54 +42,26 @@ class KTEXTEDITOR_EXPORT TemplateInterface //should be named AbstractTemplateInt
|
||||||
TemplateInterface();
|
TemplateInterface();
|
||||||
virtual ~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<QString, QString> &initialValues, QWidget *parentWindow );
|
|
||||||
|
|
||||||
public:
|
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
|
* \return true if inserting the string succeeded
|
||||||
*
|
*
|
||||||
* Use insertTemplateText(lines(), ...) to append text at end of document
|
* Use insertTemplateText(lines(), ...) to append text at end of document
|
||||||
* Template strings look like
|
* Template strings look like
|
||||||
* "for( int ${index}=0;${index}<10;${index}++) { ${cursor} };"
|
* "for( int i=0;i<10;i++) { %{cursor} };"
|
||||||
* or "%{date}"
|
* or "%{date}"
|
||||||
*
|
*
|
||||||
* This syntax is somewhat similar to the one found in the Eclipse editor or textmate.
|
* 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
|
* There are certain common placeholders (macros), which get assigned a
|
||||||
* default initialValue, If the second parameter does not a given value.
|
* default initialValue.
|
||||||
* For all others the initial value is the name of the placeholder.
|
|
||||||
*
|
*
|
||||||
* Placeholder names may only consist of a-zA-Z0-9_
|
* 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
|
* Common placeholders and values are
|
||||||
*
|
*
|
||||||
* - index: "i"
|
|
||||||
* - loginname: The current users's loginname
|
* - loginname: The current users's loginname
|
||||||
* - fullname: The current user's first and last name retrieved from kabc
|
* - fullname: The current user's first and last name retrieved from kabc
|
||||||
* - email: The current user's primary email address 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
|
* - day: current day
|
||||||
* - hostname: hostname of the computer
|
* - hostname: hostname of the computer
|
||||||
* - selection: The implementation should set this to the selected text, if any
|
* - selection: The implementation should set this to the selected text, if any
|
||||||
* - cursor: at this position the cursor will be after editing of the
|
* - cursor: The implementation should set the cursor position there, if any.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* If the editor supports some kind of smart indentation, the inserted code
|
* If the editor supports some kind of smart indentation, the inserted code
|
||||||
* should be layouted by the indenter.
|
* should be layouted by the indenter.
|
||||||
|
@ -122,12 +88,6 @@ protected:
|
||||||
* \return true if any text was inserted.
|
* \return true if any text was inserted.
|
||||||
*/
|
*/
|
||||||
virtual bool insertTemplateTextImplementation ( const Cursor &insertPosition, const QString &templateString, const QMap<QString,QString> &initialValues)=0;
|
virtual bool insertTemplateTextImplementation ( const Cursor &insertPosition, const QString &templateString, const QMap<QString,QString> &initialValues)=0;
|
||||||
|
|
||||||
/**
|
|
||||||
* DO NOT USE !!!! THIS IS USED INTERNALLY by the interface only !!!!!!
|
|
||||||
* Behaviour might change !!!!!!!
|
|
||||||
*/
|
|
||||||
bool KTE_INTERNAL_setupIntialValues(const QString &templateString, QMap<QString,QString> *initialValues);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue