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

Reply via email to