Update of /cvsroot/mahogany/M/src/classes
In directory usw-pr-cvs1:/tmp/cvs-serv10676/src/classes
Modified Files:
ComposeTemplate.cpp MessageTemplate.cpp
Log Message:
added possibility to set the message headers from templates
Index: ComposeTemplate.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/classes/ComposeTemplate.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -b -u -2 -r1.25 -r1.26
--- ComposeTemplate.cpp 4 Mar 2002 18:58:24 -0000 1.25
+++ ComposeTemplate.cpp 4 Mar 2002 20:53:27 -0000 1.26
@@ -161,6 +161,7 @@
Category_Python, // execute Python script
#endif // USE_PYTHON
- Category_Message, // the headers of the message being written
+ Category_Message, // access the headers of the message being written
Category_Original, // variables pertaining to the original message
+ Category_Headers, // set the headers of the message being written
Category_Invalid, // unknown/invalid category
Category_Max = Category_Invalid
@@ -298,5 +299,7 @@
// Expand determines the category and then calls one of these functions
- bool ExpandMisc(const String& name, String *value) const;
+ bool ExpandMisc(const String& name,
+ const wxArrayString& arguments,
+ String *value) const;
bool ExpandFile(const String& name,
const wxArrayString& arguments,
@@ -305,5 +308,7 @@
const wxArrayString& arguments,
String *value) const;
- bool ExpandCommand(const String& name, String *value) const;
+ bool ExpandCommand(const String& name,
+ const wxArrayString& arguments,
+ String *value) const;
#ifdef USE_PYTHON
bool ExpandPython(const String& name, String *value) const;
@@ -312,4 +317,8 @@
bool ExpandOriginal(const String& name, String *value) const;
+ bool SetHeaderValue(const String& name,
+ const wxArrayString& arguments,
+ String *value) const;
+
// get the signature to use (including the signature separator, if any)
String GetSignature() const;
@@ -556,4 +565,5 @@
"message",
"original",
+ "header",
};
@@ -681,5 +691,5 @@
case Category_Command:
- return ExpandCommand(name, value);
+ return ExpandCommand(name, arguments, value);
#ifdef USE_PYTHON
@@ -695,5 +705,8 @@
case Category_Misc:
- return ExpandMisc(name, value);
+ return ExpandMisc(name, arguments, value);
+
+ case Category_Headers:
+ return SetHeaderValue(name, arguments, value);
default:
@@ -704,5 +717,7 @@
bool
-VarExpander::ExpandMisc(const String& name, String *value) const
+VarExpander::ExpandMisc(const String& name,
+ const wxArrayString& arguments,
+ String *value) const
{
// deal with all special cases
@@ -846,18 +861,36 @@
bool
-VarExpander::ExpandCommand(const String& name, String *value) const
+VarExpander::ExpandCommand(const String& name,
+ const wxArrayString& arguments,
+ String *value) const
{
- // execute a command (FIXME get the wxProcess class allowing stdout
- // redirection and use it here)
+ // execute a command
MTempFileName temp;
bool ok = temp.IsOk();
- wxString filename = temp.GetName(), command;
+ wxString filename = temp.GetName();
if ( ok )
- command << name << " > " << filename;
+ {
+ wxString command = name;
+
+ // although the arguments may be included directly in the template,
+ // passing them via "?" argument mechanism allows to calculate them
+ // during run-time, i.e. it makes it possible to call an external command
+ // using the result of application of another template
+ size_t count = arguments.GetCount();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ // forbid further expansion in the arguments by quoting them
+ wxString arg = arguments[n];
+ arg.Replace("'", "\\'");
+
+ command << " '" << arg << '\'';
+ }
+
+ command << " > " << filename;
- if ( ok )
ok = system(command) == 0;
+ }
if ( ok )
@@ -868,7 +901,49 @@
wxLogSysError(_("Failed to execute the command '%s'"), name.c_str());
+ // make sure the value isn't empty to avoid message about unknown
+ // variable from the parser
+ *value = '?';
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+bool
+VarExpander::SetHeaderValue(const String& name,
+ const wxArrayString& arguments,
+ String *value) const
+{
+ if ( arguments.GetCount() != 1 )
+ {
+ wxLogError(_("${header:%s} requires exactly one argument."),
+ name.c_str());
+
+ *value = '?';
+
return FALSE;
}
+ String headerValue = arguments[0];
+
+ // is it one of the standard headers or some other one?
+ String headerName = name.Lower();
+ if ( headerName == "subject" )
+ m_cv.SetSubject(headerValue);
+ else if ( headerName == "to" )
+ m_cv.AddTo(headerValue);
+ else if ( headerName == "cc" )
+ m_cv.AddCc(headerValue);
+ else if ( headerName == "bcc" )
+ m_cv.AddBcc(headerValue);
+ // TODO: we don't have SetFrom() yet in Composer
+#if 0
+ else if ( headerName == "from" )
+ m_cv.SetFrom(headerValue);
+#endif // 0
+ else // some other header
+ m_cv.AddHeaderEntry(headerName, headerValue);
+
return TRUE;
}
@@ -1190,5 +1265,5 @@
if ( READ_CONFIG(m_profile, MP_COMPOSE_USE_SIGNATURE_SEPARATOR) )
{
- signature += "\n--";
+ signature += "--\n";
}
@@ -1197,5 +1272,8 @@
for ( size_t nLine = 0; nLine < nLineCount; nLine++ )
{
- signature << '\n' << fileSig[nLine];
+ if ( nLine )
+ signature += '\n';
+
+ signature += fileSig[nLine];
}
Index: MessageTemplate.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/classes/MessageTemplate.cpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -b -u -2 -r1.26 -r1.27
--- MessageTemplate.cpp 4 Mar 2002 19:12:25 -0000 1.26
+++ MessageTemplate.cpp 4 Mar 2002 20:53:27 -0000 1.27
@@ -83,41 +83,12 @@
// ----------------------------------------------------------------------------
-bool MessageTemplateParser::Parse(MessageTemplateSink& sink) const
+// parse the template expansion starting at the given position, return false if
+// an error was encountered while processing it
+bool
+MessageTemplateParser::ExpandTemplate(const char **ppc, String *value) const
{
- // as this is used only for diagnostic messages, start counting from 1 - as
- // people like it (unlike the programmers)
- size_t nLine = 1;
-
- // only generate something if we can
- bool doOutput = m_expander != NULL;
-
- // the template text may be coming from various sources, so make sure that
- // it doesn't have some weird newline convention
- wxString templateText = wxTextFile::Translate(m_templateText,
- wxTextFileType_Unix);
- const char *pc = templateText.c_str();
- const char *pStartOfLine = pc;
- while ( *pc )
- {
- // find next '$'
- while ( *pc && *pc != '$' )
- {
- if ( doOutput )
- {
- // normal text goes to output
- sink.Output(*pc);
- }
-
- if ( *pc == '\n' )
- {
- nLine++;
- pStartOfLine = pc;
- }
-
- pc++;
- }
+ const char *pc = *ppc;
- if ( !*pc )
- break;
+ ASSERT_MSG( *pc == '$', "we should be called for $expression only" );
// what kind of brackets do we have? some of them imply the category
@@ -134,5 +105,5 @@
switch ( bracketOpen )
{
- case '\'':
+ case '\'': // this one is kept for compatibility only, it was a typo...
case '`':
bracketClose = bracketOpen;
@@ -157,8 +128,8 @@
case '$':
// it's just escaped '$' and not start of the expansion at all
- if ( doOutput )
- sink.Output('$');
- pc++;
- continue;
+ if ( m_expander )
+ *value = '$';
+ *ppc = ++pc;
+ return TRUE;
case '\0':
@@ -177,6 +148,6 @@
wxLogWarning(_("Unexpected character at position %d in line "
"%d in the file '%s'."),
- pc - pStartOfLine + 1,
- nLine,
+ pc - m_pStartOfLine + 1,
+ m_nLine,
m_filename.c_str());
@@ -225,12 +196,8 @@
else
{
- // the message is the same as below, that's why we pass
- // ':' as an argument instead of embedding it into the
- // message directly
- wxLogWarning(_("Unexpected character '%c' at line "
- "%d, position %d in the file '%s'."),
- ':',
- nLine,
- pc - pStartOfLine,
+ wxLogWarning(_("Unexpected \":\" at line "
+ "%d, position %d in the file '%s'"),
+ m_nLine,
+ pc - m_pStartOfLine,
m_filename.c_str());
@@ -242,13 +209,45 @@
// list of arguments ahead
{
- wxString arg;
+ String arg;
do
{
- pc++; // skip '?' (first time) or ',' (subsequent ones)
-
arg.clear();
- while ( isalnum(*pc) )
+
+ // initially skip '?' (first time) or ',' (subsequent ones)
+ pc++;
+
+ // quoted argument?
+ bool quoted = *pc == '"';
+ if ( quoted )
+ pc++;
+
+ // stop on some speical chars if not quoted, otherwise
+ // only stop at the closing quote
+ while ( *pc &&
+ ((quoted && *pc != '"') ||
+ (!strchr("+-=, ", *pc) && *pc != bracketClose)) )
+ {
+ if ( *pc == '\\' )
+ {
+ // quoted character, take as is
+ arg += *++pc;
+ }
+ else if ( *pc == '$' )
+ {
+ String subarg;
+ if ( !ExpandTemplate(&pc, &subarg) )
+ {
+ return FALSE;
+ }
+
+ pc--; // compensate for the increment below
+ arg += subarg;
+ }
+ else // simple char
{
- arg += *pc++;
+ arg += *pc;
+ }
+
+ pc++;
}
@@ -293,6 +292,6 @@
wxLogWarning(_("Incorrect alignment width value at line "
"%d, position %d in the file '%s'."),
- nLine,
- pc - pStartOfLine,
+ m_nLine,
+ pc - m_pStartOfLine,
m_filename.c_str());
@@ -332,9 +331,11 @@
{
wxLogWarning(_("Unexpected character '%c' at line "
- "%d, position %d in the file '%s'."),
+ "%d, position %d in the file '%s' "
+ "(expected \"%c\" instead)."),
*pc,
- nLine,
- pc - pStartOfLine,
- m_filename.c_str());
+ m_nLine,
+ pc - m_pStartOfLine,
+ m_filename.c_str(),
+ bracketClose);
return FALSE;
@@ -346,20 +347,18 @@
// we have all the info, so we may ask the expander for the value - but
// skip all the rest if we're not generating output
- if ( !doOutput )
- continue;
-
- String value;
- if ( !m_expander->Expand(category, name, arguments, &value) )
+ if ( m_expander )
+ {
+ if ( !m_expander->Expand(category, name, arguments, value) )
{
// don't log the message if the value is not empty - this means that
// the variable *is* known, but that the expansion, for some reason,
// failed.
- if ( !value )
+ if ( value->empty() )
{
wxLogWarning(_("Unknown variable '%s' at line %d, position %d "
"in the file '%s'."),
name.c_str(),
- nLine,
- pc - pStartOfLine - name.length(),
+ m_nLine,
+ pc - m_pStartOfLine - name.length(),
m_filename.c_str());
}
@@ -372,5 +371,5 @@
if ( alignment != None )
{
- size_t len = value.length();
+ size_t len = value->length();
switch ( alignment )
{
@@ -379,9 +378,9 @@
{
// add some spaces
- value += wxString(' ', alignWidth - len);
+ *value += wxString(' ', alignWidth - len);
}
else if ( (len > alignWidth) && truncate )
{
- value.Truncate(alignWidth);
+ value->Truncate(alignWidth);
}
//else: value is already wide enough, but we don't truncate it
@@ -392,9 +391,9 @@
{
// prepend some spaces
- value = wxString(' ', alignWidth - len) + value;
+ value->Prepend(wxString(' ', alignWidth - len));
}
else if ( (len > alignWidth) && truncate )
{
- value = value.c_str() + len - alignWidth;
+ *value = value->c_str() + len - alignWidth;
}
//else: value is already wide enough, but we don't truncate it
@@ -407,11 +406,11 @@
size_t n1 = (alignWidth - len) / 2,
n2 = alignWidth - n1;
- value = wxString(' ', n1) + value + wxString(' ', n2);
+ *value = wxString(' ', n1) + *value + wxString(' ', n2);
}
else if ( (len > alignWidth) && truncate )
{
// truncate a bit at right and a bit at left side
- value = value.c_str() + (len - alignWidth) / 2;
- value.Truncate(alignWidth);
+ *value = value->c_str() + (len - alignWidth) / 2;
+ value->Truncate(alignWidth);
}
//else: value is already wide enough, but we don't truncate it
@@ -422,4 +421,55 @@
}
}
+ }
+
+ *ppc = pc;
+
+ return TRUE;
+}
+
+bool MessageTemplateParser::Parse(MessageTemplateSink& sink) const
+{
+ // const_cast
+ MessageTemplateParser *self = (MessageTemplateParser *)this;
+
+ // as this is used only for diagnostic messages, start counting from 1 - as
+ // people like it (unlike the programmers)
+ self->m_nLine = 1;
+
+ // the template text may be coming from various sources, so make sure that
+ // it doesn't have some weird newline convention
+ wxString templateText = wxTextFile::Translate(m_templateText,
+ wxTextFileType_Unix);
+ const char *pc = templateText.c_str();
+ self->m_pStartOfLine = pc;
+ while ( *pc )
+ {
+ // find next '$'
+ while ( *pc && *pc != '$' )
+ {
+ if ( m_expander )
+ {
+ // normal text goes to the output as is
+ sink.Output(*pc);
+ }
+
+ if ( *pc == '\n' )
+ {
+ self->m_nLine++;
+ self->m_pStartOfLine = pc;
+ }
+
+ pc++;
+ }
+
+ if ( !*pc )
+ break;
+
+ String value;
+ if ( !ExpandTemplate(&pc, &value) )
+ {
+ // error message already given
+ return FALSE;
+ }
sink.Output(value);
@@ -600,5 +650,5 @@
// all default templates include the signature
- value += "$SIGNATURE";
+ value += "\n$SIGNATURE";
}
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates