[M-git] Mahogany sources repository. branch master updated. v0.67-725-g837751a

"Vadim Zeitlin" <[email protected]> Wed, 2 Mar 2016 13:38:44 +0000
Newsgroups gmane.mail.mahogany.cvs
Message-ID <[email protected]>
--===============1561226580411846567==

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Mahogany sources repository.".

The branch, master has been updated
       via  837751aaced7b987f096d154ba21ef9c0f7bb629 (commit)
       via  a139633dae4d79972dfe8a8559eeb03f55166945 (commit)
       via  a937793fc184e0d1db49a62c6ab69ef4ff199318 (commit)
       via  563597fbe5893baa1fe16c2189ee7bdb90ed4b40 (commit)
       via  3ef1591625b8119b17a094e9611193d88b9f7afd (commit)
       via  87ac5aacb51125ed48aadeeee5c6494429de5801 (commit)
       via  308fcaabad0e7331a921adee2cc68c55632ff460 (commit)
       via  163bbe2e84fa7ba277c2a5063c8ee99527ef7951 (commit)
       via  963a9c672a9979cfa33be7ebed1ad5724f272f5d (commit)
       via  d5bc45b4804adfd75d1a26f321164c84e44da5b5 (commit)
       via  2e3f9dcc87736099324c17e9d01ca9ccca9af813 (commit)
       via  75aff1d9dccc4b00c30959ad00e95bb0b75b6ef0 (commit)
       via  22d1032ea35e311a7bee5815c21ab17c4f90d106 (commit)
       via  5f7fb05fd392f2f952241db8d4337bc9dc6aaae9 (commit)
       via  2b5067fe9dd2bb5620b7786aff879e1b0405b728 (commit)
       via  7df5a8c35e145afcc870955be21a7e7e3451bed8 (commit)
       via  b5028fa6b41abd67bccbd422d5bf2cc5177a5781 (commit)
       via  ab067521f4bc5e0e63262bd175076875d1c7b136 (commit)
       via  48bb1e9be3051694a616a19836cf038eb858d145 (commit)
       via  e72f06994b868b50f16b56a9495410455f69caf1 (commit)
       via  e7ad321374e3a0fde9d1e27cc5129eba46cc3f68 (commit)
       via  583f9e9d51b55c5715593995373b6e88a22d9e7f (commit)
      from  2eb4d6d2f531f88a0e1c29d7e1da47c67b0ef8ca (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 837751aaced7b987f096d154ba21ef9c0f7bb629
Author: Vadim Zeitlin <[email protected]>
Date:   Mon Feb 1 13:31:36 2016 +0100

    Don't complain about unknown https:// schema in List-Post headers
    
    Just avoid an annoying debug warning.

diff --git a/src/mail/MailFolder.cpp b/src/mail/MailFolder.cpp
index 285608d..96b3dca 100644
--- a/src/mail/MailFolder.cpp
+++ b/src/mail/MailFolder.cpp
@@ -493,7 +493,8 @@ ExtractListPostAddress(const String& listPostHeader)
                // start of an URL, get it
                if ( wxStrncmp(++p, _T("mailto:"), MAILTO_LEN) != 0 )
                {
-                  if ( wxStrncmp(p, _T("http:"), 5) != 0 )
+                  if ( wxStrncmp(p, _T("http:"), 5) != 0 &&
+                        wxStrncmp(p, _T("https:"), 6) != 0 )
                   {
                      wxLogDebug(_T("Unknown URL scheme in List-Post (%s)"),
                                 listPostHeader.c_str());

commit a139633dae4d79972dfe8a8559eeb03f55166945
Author: Vadim Zeitlin <[email protected]>
Date:   Sun Jan 31 03:42:26 2016 +0100

    Remove hard-coded paths from versit MSVS project
    
    Create the output files in standard locations.

diff --git a/src/wx/vcard/versit.vcxproj b/src/wx/vcard/versit.vcxproj
index dd2e819..b1fbf0a 100644
--- a/src/wx/vcard/versit.vcxproj
+++ b/src/wx/vcard/versit.vcxproj
@@ -96,10 +96,6 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <PrecompiledHeaderOutputFile>.\Release/versit.pch</PrecompiledHeaderOutputFile>

-      <AssemblerListingLocation>.\Release/</AssemblerListingLocation>

-      <ObjectFileName>.\Release/</ObjectFileName>

-      <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>

       <WarningLevel>Level1</WarningLevel>

       <SuppressStartupBanner>true</SuppressStartupBanner>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

@@ -110,7 +106,6 @@
     </ResourceCompile>

     <Link>

       <SuppressStartupBanner>true</SuppressStartupBanner>

-      <ProgramDatabaseFile>.\Release/versit.pdb</ProgramDatabaseFile>

       <SubSystem>Windows</SubSystem>

       <RandomizedBaseAddress>false</RandomizedBaseAddress>

       <DataExecutionPrevention>

@@ -134,10 +129,6 @@
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <PrecompiledHeaderOutputFile>.\Debug/versit.pch</PrecompiledHeaderOutputFile>

-      <AssemblerListingLocation>.\Debug/</AssemblerListingLocation>

-      <ObjectFileName>.\Debug/</ObjectFileName>

-      <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>

       <WarningLevel>Level1</WarningLevel>

       <SuppressStartupBanner>true</SuppressStartupBanner>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

@@ -149,7 +140,6 @@
     <Link>

       <SuppressStartupBanner>true</SuppressStartupBanner>

       <GenerateDebugInformation>true</GenerateDebugInformation>

-      <ProgramDatabaseFile>.\Debug/versit.pdb</ProgramDatabaseFile>

       <SubSystem>Windows</SubSystem>

       <RandomizedBaseAddress>false</RandomizedBaseAddress>

       <DataExecutionPrevention>

@@ -176,10 +166,6 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <PrecompiledHeaderOutputFile>.\Release/versit.pch</PrecompiledHeaderOutputFile>

-      <AssemblerListingLocation>.\Release/</AssemblerListingLocation>

-      <ObjectFileName>.\Release/</ObjectFileName>

-      <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>

       <WarningLevel>Level1</WarningLevel>

       <SuppressStartupBanner>true</SuppressStartupBanner>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

@@ -190,7 +176,6 @@
     </ResourceCompile>

     <Link>

       <SuppressStartupBanner>true</SuppressStartupBanner>

-      <ProgramDatabaseFile>.\Release/versit.pdb</ProgramDatabaseFile>

       <SubSystem>Windows</SubSystem>

       <RandomizedBaseAddress>false</RandomizedBaseAddress>

       <DataExecutionPrevention>

@@ -214,10 +199,6 @@
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <PrecompiledHeaderOutputFile>.\Debug/versit.pch</PrecompiledHeaderOutputFile>

-      <AssemblerListingLocation>.\Debug/</AssemblerListingLocation>

-      <ObjectFileName>.\Debug/</ObjectFileName>

-      <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>

       <WarningLevel>Level1</WarningLevel>

       <SuppressStartupBanner>true</SuppressStartupBanner>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

@@ -229,7 +210,6 @@
     <Link>

       <SuppressStartupBanner>true</SuppressStartupBanner>

       <GenerateDebugInformation>true</GenerateDebugInformation>

-      <ProgramDatabaseFile>.\Debug/versit.pdb</ProgramDatabaseFile>

       <SubSystem>Windows</SubSystem>

       <RandomizedBaseAddress>false</RandomizedBaseAddress>

       <DataExecutionPrevention>


commit a937793fc184e0d1db49a62c6ab69ef4ff199318
Author: Vadim Zeitlin <[email protected]>
Date:   Sun Jan 31 03:13:41 2016 +0100

    Update MSVS project files to MSVS 2015
    
    Just change the toolset version and wxWidgets libraries path.

diff --git a/M.vcxproj b/M.vcxproj
index 9e29c8d..dd0c3c8 100644
--- a/M.vcxproj
+++ b/M.vcxproj
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

   <ItemGroup Label="ProjectConfigurations">

     <ProjectConfiguration Include="Debug DLL|Win32">

       <Configuration>Debug DLL</Configuration>

@@ -38,47 +38,48 @@
     <ProjectGuid>{1515C8EB-5C72-43DF-9D3A-0703F155F268}</ProjectGuid>

     <RootNamespace>M</RootNamespace>

     <Keyword>Win32Proj</Keyword>

+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

     <ConfigurationType>Application</ConfigurationType>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120_xp</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'" Label="Configuration">

     <ConfigurationType>Application</ConfigurationType>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

     <ConfigurationType>Application</ConfigurationType>

     <CharacterSet>NotSet</CharacterSet>

-    <PlatformToolset>v120_xp</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'" Label="Configuration">

     <ConfigurationType>Application</ConfigurationType>

     <CharacterSet>NotSet</CharacterSet>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

     <ConfigurationType>Application</ConfigurationType>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|x64'" Label="Configuration">

     <ConfigurationType>Application</ConfigurationType>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

     <ConfigurationType>Application</ConfigurationType>

     <CharacterSet>NotSet</CharacterSet>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|x64'" Label="Configuration">

     <ConfigurationType>Application</ConfigurationType>

     <CharacterSet>NotSet</CharacterSet>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

@@ -297,7 +298,7 @@
     <Link>

       <AdditionalDependencies>imap.lib;compface.lib;dspam.lib;versit.lib;winmm.lib;comctl32.lib;rpcrt4.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>

       <OutputFile>$(OutDir)M.exe</OutputFile>

-      <AdditionalLibraryDirectories>$(OutDir);$(wxwin)\lib\vc120_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

+      <AdditionalLibraryDirectories>$(OutDir);$(wxwin)\lib\vc140_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

       <GenerateDebugInformation>true</GenerateDebugInformation>

       <SubSystem>Windows</SubSystem>

       <StackReserveSize>10000000</StackReserveSize>

@@ -1537,4 +1538,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

   <ImportGroup Label="ExtensionTargets">

   </ImportGroup>

-</Project>

+</Project>
\ No newline at end of file
diff --git a/Mconfig.vcxproj b/Mconfig.vcxproj
index 9292950..d59af22 100644
--- a/Mconfig.vcxproj
+++ b/Mconfig.vcxproj
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

   <ItemGroup Label="ProjectConfigurations">

     <ProjectConfiguration Include="Debug|Win32">

       <Configuration>Debug</Configuration>

@@ -23,27 +23,28 @@
     <ProjectGuid>{86C1D2C7-C961-4017-88E8-63D0BCCBD0D5}</ProjectGuid>

     <RootNamespace>config</RootNamespace>

     <Keyword>MakeFileProj</Keyword>

+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

     <ConfigurationType>Utility</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

-    <PlatformToolset>v120_xp</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

     <ConfigurationType>Utility</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

-    <PlatformToolset>v120_xp</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

     <ConfigurationType>Utility</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

     <ConfigurationType>Utility</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/lib/compface/compface.vcxproj b/lib/compface/compface.vcxproj
index 016a441..22b76fb 100644
--- a/lib/compface/compface.vcxproj
+++ b/lib/compface/compface.vcxproj
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

   <ItemGroup Label="ProjectConfigurations">

     <ProjectConfiguration Include="Debug|Win32">

       <Configuration>Debug</Configuration>

@@ -20,31 +20,32 @@
   </ItemGroup>

   <PropertyGroup Label="Globals">

     <ProjectGuid>{0E9F4403-1AA1-4824-A99F-041B1BF18D14}</ProjectGuid>

+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120_xp</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120_xp</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/lib/dspam/dspam.vcxproj b/lib/dspam/dspam.vcxproj
index 79a00ec..eb9754d 100644
--- a/lib/dspam/dspam.vcxproj
+++ b/lib/dspam/dspam.vcxproj
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

   <ItemGroup Label="ProjectConfigurations">

     <ProjectConfiguration Include="Debug|Win32">

       <Configuration>Debug</Configuration>

@@ -21,31 +21,32 @@
   <PropertyGroup Label="Globals">

     <ProjectGuid>{62156246-DCEA-4713-95E0-C01F595F1A20}</ProjectGuid>

     <RootNamespace>dspam</RootNamespace>

+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120_xp</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120_xp</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/lib/imap/imap.vcxproj b/lib/imap/imap.vcxproj
index 3ce6906..11d96e8 100644
--- a/lib/imap/imap.vcxproj
+++ b/lib/imap/imap.vcxproj
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

   <ItemGroup Label="ProjectConfigurations">

     <ProjectConfiguration Include="Debug|Win32">

       <Configuration>Debug</Configuration>

@@ -21,31 +21,32 @@
   <PropertyGroup Label="Globals">

     <ProjectGuid>{457cfec8-5c3f-4c7e-98a6-b65e1de22682}</ProjectGuid>

     <RootNamespace>imap</RootNamespace>

+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120_xp</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120_xp</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

     <CharacterSet>MultiByte</CharacterSet>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

diff --git a/src/wx/vcard/versit.vcxproj b/src/wx/vcard/versit.vcxproj
index 97f91bf..dd2e819 100644
--- a/src/wx/vcard/versit.vcxproj
+++ b/src/wx/vcard/versit.vcxproj
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

   <ItemGroup Label="ProjectConfigurations">

     <ProjectConfiguration Include="Debug|Win32">

       <Configuration>Debug</Configuration>

@@ -21,27 +21,28 @@
   <PropertyGroup Label="Globals">

     <ProjectGuid>{E46C11C7-5924-4F7C-B82E-5BEB8856A8BC}</ProjectGuid>

     <RootNamespace>versit</RootNamespace>

+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

     <ConfigurationType>DynamicLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

-    <PlatformToolset>v120_xp</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

     <ConfigurationType>DynamicLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

-    <PlatformToolset>v120_xp</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

     <ConfigurationType>DynamicLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

     <ConfigurationType>DynamicLibrary</ConfigurationType>

     <UseOfMfc>false</UseOfMfc>

-    <PlatformToolset>v120</PlatformToolset>

+    <PlatformToolset>v140_xp</PlatformToolset>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">


commit 563597fbe5893baa1fe16c2189ee7bdb90ed4b40
Author: Vadim Zeitlin <[email protected]>
Date:   Sun Jan 31 03:31:05 2016 +0100

    Compilation fix for MSVS 2015: don't use CRT FILE details
    
    The existing code using FILE::_tmpfname doesn't compile any more with MSVS
    2015 version of the CRT which declares FILE as an opaque pointer but luckily
    it doesn't seem like we need the workarounds any more because tmpfile() does
    work correctly now (and since many, many years) and unlinking seems to work
    fine too.

diff --git a/lib/imap/src/osdep/nt/yunchan.c b/lib/imap/src/osdep/nt/yunchan.c
index 8c1f690..5179141 100644
--- a/lib/imap/src/osdep/nt/yunchan.c
+++ b/lib/imap/src/osdep/nt/yunchan.c
@@ -208,53 +208,6 @@ unsigned long unix_crlflen (STRING *s)
   return i;
 }
 
-/* Undoubtably, I'm going to regret these two routines in the future.  I
- * regret them now.  Their purpose is to work around two problems in the
- * VC++ 6.0 C library:
- *  (1) tmpfile() creates the file in the current directory instead of a
- *	temporary directory
- *  (2) tmpfile() and fclose() think that on NT systems, it works to unlink
- *	the file while it's still open, so there's no need for the _tmpfname
- *	hook at fclose().  Unfortunately, that doesn't work in Win2K.
- * I would be delighted to have a better alternative.
- */
-
-#undef fclose			/* use the real fclose() in close_file() */
-
-/* Substitute for Microsoft's tmpfile() that uses the real temporary directory
- * Returns: FILE structure if success, NIL if failure
- */
-
-FILE *create_tempfile (void)
-{
-  FILE *ret = NIL;
-  char *s = _tempnam (getenv ("TEMP"),"msg");
-  if (s) {			/* if got temporary name... */
-				/* open file, and stash name on _tmpfname */
-    if (ret = fopen (s,"w+b")) ret->_tmpfname = s;
-    else fs_give ((void **) &s);/* flush temporary string */
-  }
-  return ret;
-}
-
-
-/* Substitute for Microsoft's fclose() that always flushes _tmpfname
- * Returns: FILE structure if success, NIL if failure
- */
-
-int close_file (FILE *stream)
-{
-  int ret;
-  char *s = stream->_tmpfname;
-  stream->_tmpfname = NIL;	/* just in case fclose() tries to delete it */
-  ret = fclose (stream);	/* close the file */
-  if (s) {			/* was there a _tmpfname? */
-    unlink (s);			/* yup, delete it */
-    fs_give ((void **) &s);	/* and flush the name */
-  }
-  return ret;
-}
-
 /* Get password from console
  * Accepts: prompt
  * Returns: password
diff --git a/lib/imap/src/osdep/nt/yunchan.h b/lib/imap/src/osdep/nt/yunchan.h
index 25d6056..2224e22 100644
--- a/lib/imap/src/osdep/nt/yunchan.h
+++ b/lib/imap/src/osdep/nt/yunchan.h
@@ -66,8 +66,6 @@
 #define LOG_NDELAY	0x08	/* don't delay open */
 #define LOG_NOWAIT	0x10	/* if forking to log on console, don't wait() */
 
-#define tmpfile create_tempfile
-#define fclose close_file
 #define fsync _commit
 #define ftruncate chsize
 #define gethostid clock
@@ -81,6 +79,4 @@ void syslog (int priority,const char *message,...);
 unsigned long unix_crlfcpy (char **dst,unsigned long *dstl,char *src,
 			    unsigned long srcl);
 unsigned long unix_crlflen (STRING *s);
-FILE *create_tempfile (void);
-int close_file (FILE *stream);
 char *getpass (const char *prompt);

commit 3ef1591625b8119b17a094e9611193d88b9f7afd
Author: Vadim Zeitlin <[email protected]>
Date:   Sun Jan 31 03:30:41 2016 +0100

    Compilation fix for MSVS 2015: use _tzname and _daylight
    
    The versions without underscores don't exist any more in MSVS 2015 CRT.

diff --git a/lib/imap/src/osdep/nt/env_nt.c b/lib/imap/src/osdep/nt/env_nt.c
index e0352ea..056cbfe 100644
--- a/lib/imap/src/osdep/nt/env_nt.c
+++ b/lib/imap/src/osdep/nt/env_nt.c
@@ -167,7 +167,7 @@ static void do_date (char *date,char *prefix,char *fmt,int suffix)
   if (suffix) {			/* append timezone suffix if desired */
     char *tz;
     tzset ();			/* get timezone from TZ environment stuff */
-    tz = tzname[daylight ? (((struct tm *) t)->tm_isdst > 0) : 0];
+    tz = _tzname[_daylight ? (((struct tm *) t)->tm_isdst > 0) : 0];
     if (tz && tz[0]) {
       char *s;
       for (s = tz; *s; s++) if (*s & 0x80) return;

commit 87ac5aacb51125ed48aadeeee5c6494429de5801
Author: Vadim Zeitlin <[email protected]>
Date:   Sun Jan 31 03:29:40 2016 +0100

    Don't pass extraneous argument to sprintf() in c-client code
    
    Only show the error description, not the chunk of whichever text we failed to
    write to file, in the error message given when copying to MH mailbox failed.
    
    Thanks to MSVS 2015 for the warning.

diff --git a/lib/imap/src/osdep/nt/mhnt.c b/lib/imap/src/osdep/nt/mhnt.c
index 50a579c..ec768cb 100644
--- a/lib/imap/src/osdep/nt/mhnt.c
+++ b/lib/imap/src/osdep/nt/mhnt.c
@@ -943,7 +943,7 @@ long mh_ping (MAILSTREAM *stream)
 	    unlink (LOCAL->buf);/* flush this file */
 	  }
 	  sprintf (tmp,"Message copy to MH mailbox failed: %.80s",
-		   s,strerror (errno));
+		   strerror (errno));
 	  mm_log (tmp,ERROR);
 	  r = 0;		/* stop the snarf in its tracks */
 	}
diff --git a/lib/imap/src/osdep/unix/mh.c b/lib/imap/src/osdep/unix/mh.c
index 0226b7a..98ca35f 100644
--- a/lib/imap/src/osdep/unix/mh.c
+++ b/lib/imap/src/osdep/unix/mh.c
@@ -937,7 +937,7 @@ long mh_ping (MAILSTREAM *stream)
 	    unlink (LOCAL->buf);/* flush this file */
 	  }
 	  sprintf (tmp,"Message copy to MH mailbox failed: %.80s",
-		   s,strerror (errno));
+		   strerror (errno));
 	  mm_log (tmp,ERROR);
 	  r = 0;		/* stop the snarf in its tracks */
 	}

commit 308fcaabad0e7331a921adee2cc68c55632ff460
Author: Vadim Zeitlin <[email protected]>
Date:   Fri Oct 16 03:16:29 2015 +0200

    Use system theme style for wxFolderTree under MSW
    
    This is needed for consistency with the wxListCtrl used by wxMessageView which
    uses the system theme by default with the latest wxMSW, so use
    wxTR_TWIST_BUTTONS which enables its use for wxTreeCtrl too.

diff --git a/src/gui/wxFolderTree.cpp b/src/gui/wxFolderTree.cpp
index 6d1f76d..c0ffc80 100644
--- a/src/gui/wxFolderTree.cpp
+++ b/src/gui/wxFolderTree.cpp
@@ -1705,7 +1705,9 @@ wxFolderTreeImpl::wxFolderTreeImpl(wxFolderTree *sink,
                                    wxWindow *parent, wxWindowID id,
                                    const wxPoint& pos, const wxSize& size)
                 : wxPTreeCtrl(_T("FolderTree"), parent, id, pos, size,
-                              wxTR_DEFAULT_STYLE | wxTR_EDIT_LABELS)
+                              wxTR_DEFAULT_STYLE |
+                              wxTR_TWIST_BUTTONS |
+                              wxTR_EDIT_LABELS)
 {
    // init member vars
    m_current = NULL;

commit 163bbe2e84fa7ba277c2a5063c8ee99527ef7951
Author: Vadim Zeitlin <[email protected]>
Date:   Fri Jul 24 16:08:33 2015 +0200

    No changes, just fix an annoyingly widespread typo.
    
    Fix all occurrence of the misspelt "occurence".

diff --git a/include/MFStatus.h b/include/MFStatus.h
index 16b349e..585265f 100644
--- a/include/MFStatus.h
+++ b/include/MFStatus.h
@@ -67,7 +67,7 @@ struct MailFolderStatus
 };
 
 /**
-   Formats a message replacing the occurences of the format specifiers with the
+   Formats a message replacing the occurrences of the format specifiers with the
    data. The format specifiers (listed with their meanings) are:
 
       %f          folder name
diff --git a/include/mail/FolderPool.h b/include/mail/FolderPool.h
index 77e3b59..bf06963 100644
--- a/include/mail/FolderPool.h
+++ b/include/mail/FolderPool.h
@@ -65,7 +65,7 @@ public:
      DecRef()'d by the caller.
 
      We ignore the login parameter if it is empty but using this "feature" is
-     just a sign of bad design and all occurences of this should go away:
+     just a sign of bad design and all occurrences of this should go away:
      unfortunately, currently we don't keep the login used to open the folder
      anywhere so when we want to close the folder later, for example, we don't
      have the login any more and our only hope is that we have only one folder
diff --git a/locale/pouniq.pl b/locale/pouniq.pl
index 15024f4..dd0f308 100755
--- a/locale/pouniq.pl
+++ b/locale/pouniq.pl
@@ -48,7 +48,7 @@ while (<>) {
         else {                              # end of msgid
             if ( exists $messages{$msgid} ) {
                 $dupFound = 1;
-                printf "Duplicate entry found: msgid = '%s', first occurence " .
+                printf "Duplicate entry found: msgid = '%s', first occurrence " .
                        "at line %d, another at line %d\n",
                        $msgid, $messages{$msgid}, $. - 1;
                 $skip = 1;
diff --git a/src/classes/ComposeTemplate.cpp b/src/classes/ComposeTemplate.cpp
index bf7a764..f4ccad3 100644
--- a/src/classes/ComposeTemplate.cpp
+++ b/src/classes/ComposeTemplate.cpp
@@ -1611,7 +1611,7 @@ VarExpander::DoQuoteOriginal(bool isQuote, String *value) const
 
 extern bool TemplateNeedsHeaders(const String& templateValue)
 {
-   // check if there are any occurences of "${message:xxx}" in the template
+   // check if there are any occurrences of "${message:xxx}" in the template
    //
    // TODO: really parse it using a specialized expanded and without any
    //       sink, just checking if message category appears in it
diff --git a/src/gui/ClickURL.cpp b/src/gui/ClickURL.cpp
index f1d9622..5dbce74 100644
--- a/src/gui/ClickURL.cpp
+++ b/src/gui/ClickURL.cpp
@@ -418,7 +418,7 @@ void ClickableURL::OpenInBrowser(int options) const
                   // this is a bit naive but should work as -1 can't appear
                   // elsewhere in the DDE topic, normally
                   if ( ddeCmd.Replace("-1", "0",
-                                      FALSE /* only first occurence */) == 1 )
+                                      FALSE /* only first occurrence */) == 1 )
                   {
                      // and also replace the parameters
                      if ( ddeCmd.Replace("%1", m_url, FALSE) == 1 )
diff --git a/src/gui/wxComposeView.cpp b/src/gui/wxComposeView.cpp
index 644b2cb..34e4045 100644
--- a/src/gui/wxComposeView.cpp
+++ b/src/gui/wxComposeView.cpp
@@ -3166,7 +3166,7 @@ wxComposeView::DoInitText(Message *msgOrig)
 
       if ( m_textToQuote.empty() )
       {
-         // we don't want to quote anything at all, so remove all occurences of
+         // we don't want to quote anything at all, so remove all occurrences of
          // $QUOTE and/or $TEXT templates in the string -- and also remove
          // anything preceding them assuming that it can only be the
          // attribution line which shouldn't be left if we don't quote anything
@@ -3178,7 +3178,7 @@ wxComposeView::DoInitText(Message *msgOrig)
          const wxChar *pcStart = templateValue.c_str();
          for ( const wxChar *pc = pcStart; ; )
          {
-            // find and skip over the next macro occurence
+            // find and skip over the next macro occurrence
             pc = wxStrchr(pc, _T('$'));
             if ( !pc++ )
                break;
diff --git a/src/gui/wxTextDialog.cpp b/src/gui/wxTextDialog.cpp
index 8f4f8d7..42cc7dd 100644
--- a/src/gui/wxTextDialog.cpp
+++ b/src/gui/wxTextDialog.cpp
@@ -68,7 +68,7 @@ private:
 
    // find dialog events
 
-   // find next occurence
+   // find next occurrence
    void OnFindDialogNext(wxFindDialogEvent& event);
 
    // find dialog has been closed
diff --git a/src/gui/wxllist.cpp b/src/gui/wxllist.cpp
index 4c0147c..16b0b97 100644
--- a/src/gui/wxllist.cpp
+++ b/src/gui/wxllist.cpp
@@ -86,7 +86,7 @@
 
 // FIXME under MSW, this constant is needed to make the thing properly redraw
 //       itself - I don't know where the size calculation error is and I can't
-//       waste time looking for it right now. Search for occurences of
+//       waste time looking for it right now. Search for occurrences of
 //       MSW_CORRECTION to find all the places where I did it.
 #ifdef __WXMSW__
    static const int MSW_CORRECTION = 10;
diff --git a/src/gui/wxlwindow.cpp b/src/gui/wxlwindow.cpp
index a24c009..d9eb31f 100644
--- a/src/gui/wxlwindow.cpp
+++ b/src/gui/wxlwindow.cpp
@@ -1406,7 +1406,7 @@ wxLayoutWindow::Find(const wxString &needle,
       RequestUpdate();
 
       // advance beyond the end of the current match so that FindAgain() finds
-      // the next occurence (if any), not the same one
+      // the next occurrence (if any), not the same one
       m_llist->MoveCursorHorizontally(1);
 
       return true;
diff --git a/src/mail/ThreadJWZ.cpp b/src/mail/ThreadJWZ.cpp
index 65975b1..4549f70 100644
--- a/src/mail/ThreadJWZ.cpp
+++ b/src/mail/ThreadJWZ.cpp
@@ -73,14 +73,14 @@
 
 // XNOFIXME: put this code in strutil.cpp.
 //
-// Removes all occurences of Re: Re[n]: Re(n):
+// Removes all occurrences of Re: Re[n]: Re(n):
 // without considering the case, and remove unneeded
 // spaces (start, end, or multiple consecutive spaces).
 // Reply prefixes are removed only at the start of the
 // string or just after a list prefix (i.e. [ListName]).
 //
 // Returns the resulting string. replyPrefixSeen is set
-// to true if at least one occurence of 'Re: ', 'Re[n]: '
+// to true if at least one occurrence of 'Re: ', 'Re[n]: '
 // or 'Re(n): ' has been removed. It is set to false
 // otherwise.
 //

commit 963a9c672a9979cfa33be7ebed1ad5724f272f5d
Author: Vadim Zeitlin <[email protected]>
Date:   Fri Jul 24 16:07:50 2015 +0200

    Document setting up Python for Windows build.
    
    Include python.vsprops from the project file and document that it needs to be
    created.

diff --git a/.gitignore b/.gitignore
index cbb5076..033fb16 100755
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ include/config.h
 lib/dspam/src/auto-config.h
 lib/imap/src/osdep/nt/ip_nt.c
 lib/imap/src/osdep/nt/osdep.h
+python.vsprops
 release/
 src/Python/HeaderInfo_swig.cpp
 src/Python/MDialogs_swig.cpp
diff --git a/M.vcxproj b/M.vcxproj
index f472f27..9e29c8d 100644
--- a/M.vcxproj
+++ b/M.vcxproj
@@ -83,6 +83,9 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

   </ImportGroup>

+  <ImportGroup Label="PropertySheets">

+    <Import Project="python.vsprops" Condition="Exists('python.vsprops')" />

+  </ImportGroup>

   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

   </ImportGroup>

@@ -1534,4 +1537,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

   <ImportGroup Label="ExtensionTargets">

   </ImportGroup>

-</Project>
\ No newline at end of file
+</Project>

diff --git a/doc/build_win.txt b/doc/build_win.txt
index fb29c71..c255f2e 100644
--- a/doc/build_win.txt
+++ b/doc/build_win.txt
@@ -52,9 +52,22 @@ b) Python
 
    If you want to build Mahogany with an embedded Python interpreter, you need
 to have Python 2.6 or 2.7 built with the same compiler you use for building
-Mahogany itself installed. You also need to add the path to include
-subdirectory of your Python installation to the "Include files" list in
-"Tools|Options|Projects and Solutions|VC++ Directories".
+Mahogany itself installed. You also need to create python.vsprops file in the
+root Mahogany directory with the following contents to allow Mahogany build
+find your Python headers:
+
+   <?xml version="1.0" encoding="utf-8"?>
+   <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+     <ImportGroup Label="PropertySheets" />
+     <PropertyGroup Label="UserMacros" />
+     <PropertyGroup />
+     <ItemDefinitionGroup>
+       <ClCompile>
+         <AdditionalIncludeDirectories>c:\full\path\your\Python\2.7.x\include</AdditionalIncludeDirectories>
+       </ClCompile>
+     </ItemDefinitionGroup>
+     <ItemGroup />
+   </Project>
 
    Otherwise you may simply remove or comment out the line #defining USE_PYTHON
 in include/config_nt.h to disable embedded Python. You will also have to

commit d5bc45b4804adfd75d1a26f321164c84e44da5b5
Author: Vadim Zeitlin <[email protected]>
Date:   Fri Jul 24 16:03:12 2015 +0200

    Update Windows build instructions to reflect the current reality.
    
    Update MSVC version used to build.
    
    Replace mentions of svn with git.
    
    Don't document building with Cygwin, this is not certain to work and is
    probably not interesting to many people in practice anyhow. We definitely
    shouldn't recommend using gcc 2.95 any more, this is just a wrong century for
    it.

diff --git a/doc/build_win.txt b/doc/build_win.txt
index 5bb56bf..fb29c71 100644
--- a/doc/build_win.txt
+++ b/doc/build_win.txt
@@ -2,26 +2,22 @@ File:		build_win.txt
 Summary:	contains instructions for building Mahogany under MS Windows
 Audience:	Mahogany developers
 Author:		Vadim Zeitlin <[email protected]>
-Modified by:	Nerijus Baliunas <[email protected]> (cygwin part)
-Last modified:	2009-12-05
-Version:	the information in this file applies to the svn sources
+Last modified:	2015-07-24
+Version:	the information in this file applies to git master
 
 0. Requirements
 ---------------
 
-a) a compiler: currently, the supported compilers for building Mahogany are
-   MS Visual C++ 9 (a.k.a. Visual Studio 2008) and cygwin. Previous versions
-   of Visual C++ (7.1/2005) could probably be used as well but the last
-   version of the project/solution for VC 7.1 was in svn r7575 and you would
-   need to check it out manually and possible update, i.e. there is no
-   guarantee that it is going to work out of the box and probably will require
-   some effort from your part.
+a) Microsoft Visual C++ compiler: currently, version 2013 is used for building
+   Mahogany. Older versions of Visual C++ (back to 2010) could probably be
+   still used as well but were not recently tested. Newer versions (2015 as of
+   this writing) can almost certainly be used as well.
 
-   If you are interested in building using another compiler (mingw32, BC++)
+   If you are interested in building using another compiler (e.g. mingw32)
    please contact us and we will try to help you.
 
-b) svn client: you need to have daily access to Mahogany (and sometimes
-   wxWidgets) source tree, and the svn is the only way to keep up to date.
+b) Git: you need to have access to Mahogany (and sometimes wxWidgets) source
+   tree.
 
 c) GNU m4 from cygwin tools: this is not an absolute requirement, however you
    will not be able to compile *.mid (Mahogany Interface Description) files if
@@ -39,17 +35,12 @@ a) wxWidgets
    Mahogany depends on wxWidgets and prior to compiling Mahogany you need to
 build the wxMSW library.
 
-   Mahogany requires wxWidgets 2.9 (building with 2.8 should still be possible
-but the project files would need to be modified). The latest 2.9.x release
+   Mahogany requires wxWidgets 3.0 or later. The latest available 3.0.x release
 should be used.
 
    Before building Mahogany you will need to build wxWidgets. To do it, you
-should open build/msw/wx_vc9.sln in wxWidgets directory and build all projects
-in it. You may use extra\scripts\wxmsw_setup.h file instead of the standard
-setup.h when building if you want to disable all the features not needed by
-Mahogany but doing this is optional and you should revert to the standard
-wx/setup.h if using wxmsw_setup.h results in errors (it is not always up to
-date...).
+should open build/msw/wx_vc12.sln in wxWidgets directory and build all projects
+in it.
 
    Finally, set wxwin environment variable to the location of wxWidgets
 sources before opening M.sln as it uses it to find wxWidgets headers and
@@ -60,11 +51,10 @@ b) Python
 ---------
 
    If you want to build Mahogany with an embedded Python interpreter, you need
-to have Python 2.6 installed (alternatively, you may build any Python from
-sources using VC 9 but Python 2.6 is built with this compiler out of the box
-which explains why using it is the best). You also need to add the path to
-include subdirectory of your Python installation to the "Include files" list
-in "Tools|Options|Projects and Solutions|VC++ Directories".
+to have Python 2.6 or 2.7 built with the same compiler you use for building
+Mahogany itself installed. You also need to add the path to include
+subdirectory of your Python installation to the "Include files" list in
+"Tools|Options|Projects and Solutions|VC++ Directories".
 
    Otherwise you may simply remove or comment out the line #defining USE_PYTHON
 in include/config_nt.h to disable embedded Python. You will also have to
@@ -93,59 +83,4 @@ the debug configuration and run it under debugger, this often provides valuable
 additional information.
 
 
-2. Cygwin
----------
-
-a) Build process
-----------------
-
-g++ 3.x can not compile Mahogany currently, so I used g++ 2.95.3. As compiler
-version should be the same when compiling both wxWidgets and Mahogany, we should
-use g++ 2.95.3 for compiling wxWidgets as well. Just use
-
-cd <path to wxWidgets sources>
-mkdir build.cygwin.gcc295
-cd build.cygwin.gcc295
-CC=gcc-2 CXX=g++-2 ../configure
-make
-make install
-
-cd <path to Mahogany sources>
-mkdir build.cygwin.gcc295
-cd build.cygwin.gcc295
-CC=gcc-2 CXX=g++-2 ../configure --with-modules=static
-make
-make install
-
-in cygwin bash shell.
-
-You can also compile with -mno-cygwin switch, i.e. mingw version. Use
-CC='gcc-2 -mno-cygwin' CXX='g++-2 -mno-cygwin' OSTYPE=mingw ../configure --with-modules=static
-
-
-b) Common problems
-------------------
-
-Linking Mahogany compiled with debug info requires a lot of memory, so please
-disable debugging if you experience out of memory problems.
-
-SSL does not work with cygwin.
-
-IMAP does not work with mingw.
-
-
-3. WINE
--------
-
-Although it's not for building under MS Windows, we'll describe it here.
-
-a) Build process
-----------------
-
-cd <path to Mahogany sources>
-mkdir build.wine
-cd build.wine
-CC=winegcc CXX=wineg++ ../configure --without-python --without-dspam --with-modules=static --disable-dialup --without-ssl
-make
-
 vi: ts=8 sw=3 nolist nocin ai:

commit 2e3f9dcc87736099324c17e9d01ca9ccca9af813
Author: Vadim Zeitlin <[email protected]>
Date:   Fri Jul 24 15:53:51 2015 +0200

    Minor optimization to folder status updating in the tree.
    
    Read MP_FTREE_FORMAT only once as we always need its value anyhow now to
    decide whether we're updating the status in the tree at all now, after the
    previous commit.
    
    This also allows to get rid of GetLabelSuffix() method, simplifying the code a
    little.

diff --git a/src/gui/wxFolderTree.cpp b/src/gui/wxFolderTree.cpp
index 7b73266..6d1f76d 100644
--- a/src/gui/wxFolderTree.cpp
+++ b/src/gui/wxFolderTree.cpp
@@ -220,7 +220,9 @@ public:
 
       // set the "own" status for this folder, this doesn't always change the
       // folder appearance as GetShownStatus() might stay unchanged
-   void SetStatus(wxTreeCtrl *tree, const MailFolderStatus& status);
+   void SetStatus(wxTreeCtrl *tree,
+                  const String& statusFormat,
+                  MailFolderStatus& status);
 
       // translate MailFolder status to tree item status
    static Status GetTreeStatusFromMf(const MailFolderStatus& status);
@@ -246,10 +248,6 @@ protected:
       // update the status of the folder shown on screen
    void UpdateShownStatus(wxTreeCtrl *tree, Status statusShownBefore);
 
-   // get the label suffix, i.e. the part which is added to the label in the
-   // tree to show the number of messages in the folder
-   String GetLabelSuffix(const MailFolderStatus& status) const;
-
 private:
    // not implemented
    wxFolderTreeNode(const wxFolderTreeNode&);
@@ -1333,8 +1331,9 @@ wxFolderTreeNode::wxFolderTreeNode(wxTreeCtrl *tree,
    // don't bother getting status for which we don't show the status in the
    // tree anyhow
    Profile_obj profile(folder->GetProfile());
+   const String statusFormat = READ_CONFIG_TEXT(profile, MP_FTREE_FORMAT);
    const bool
-      hasStatus = !READ_CONFIG_TEXT(profile, MP_FTREE_FORMAT).empty()
+      hasStatus = !statusFormat.empty()
                      && MfStatusCache::Get()->GetStatus(fullname, &status);
 
    int image = GetFolderIconForDisplay(folder);
@@ -1351,7 +1350,12 @@ wxFolderTreeNode::wxFolderTreeNode(wxTreeCtrl *tree,
       if ( hasStatus )
       {
          // show the number of messages in the tree
-         label += GetLabelSuffix(status);
+         label += FormatFolderStatusString
+                  (
+                     statusFormat,
+                     fullname,
+                     &status
+                  );
       }
       //else: no status, don't show anything
 
@@ -1373,7 +1377,7 @@ wxFolderTreeNode::wxFolderTreeNode(wxTreeCtrl *tree,
    // restore cached status
    if ( hasStatus )
    {
-      SetStatus(tree, status);
+      SetStatus(tree, statusFormat, status);
    }
 }
 
@@ -1381,26 +1385,6 @@ wxFolderTreeNode::wxFolderTreeNode(wxTreeCtrl *tree,
 // wxFolderTreeNode status code
 // ----------------------------------------------------------------------------
 
-String wxFolderTreeNode::GetLabelSuffix(const MailFolderStatus& mfStatus) const
-{
-   Profile_obj profile(GetFolder()->GetProfile());
-
-   String fmt = READ_CONFIG(profile, MP_FTREE_FORMAT);
-   if ( fmt.empty() )
-   {
-      // don't bother calling FormatFolderStatusString
-      return fmt;
-   }
-
-   return FormatFolderStatusString
-          (
-            fmt,
-            GetFolder()->GetFullName(),     // name
-            (MailFolderStatus *)&mfStatus,  // const_cast is harmless
-            NULL                            // don't use mail folder
-          );
-}
-
 /* static */
 wxFolderTreeNode::Status
 wxFolderTreeNode::GetTreeStatusFromMf(const MailFolderStatus& mfStatus)
@@ -1516,7 +1500,8 @@ void wxFolderTreeNode::OnChildStatusChange(wxTreeCtrl *tree,
 }
 
 void wxFolderTreeNode::SetStatus(wxTreeCtrl *tree,
-                                 const MailFolderStatus& mfStatus)
+                                 const String& statusFormat,
+                                 MailFolderStatus& mfStatus)
 {
    Status status = GetTreeStatusFromMf(mfStatus);
 
@@ -1531,7 +1516,12 @@ void wxFolderTreeNode::SetStatus(wxTreeCtrl *tree,
    //else: status (i.e. colour) didn't change
 
    // change label if we show the number of messages in it
-   String suffix = GetLabelSuffix(mfStatus);
+   const String suffix = FormatFolderStatusString
+                         (
+                           statusFormat,
+                           GetFolder()->GetFullName(),
+                           &mfStatus
+                         );
    if ( !suffix.empty() )
    {
       wxString textOld = tree->GetItemText(GetId()),
@@ -3402,7 +3392,8 @@ void wxFolderTreeImpl::ProcessMsgNumberChange(const wxString& folderName)
    //     we'd have to rescan the tree completely each time the user does "show
    //     hidden folders in tree"
    Profile_obj profile(folder->GetProfile());
-   if ( READ_CONFIG_TEXT(profile, MP_FTREE_FORMAT).empty() )
+   const String statusFormat = READ_CONFIG_TEXT(profile, MP_FTREE_FORMAT);
+   if ( statusFormat.empty() )
    {
       wxLogTrace(M_TRACE_MFSTATUS,
                  _T("Folder tree: ignoring it because we don't show status"));
@@ -3492,7 +3483,7 @@ void wxFolderTreeImpl::ProcessMsgNumberChange(const wxString& folderName)
 
    // and do update its status
    wxFolderTreeNode *node = GetFolderTreeNode(item);
-   node->SetStatus(this, status);
+   node->SetStatus(this, statusFormat, status);
 
    wxLogTrace(M_TRACE_MFSTATUS, _T("Folder tree: updated status for '%s'"),
               folderName.c_str());

commit 75aff1d9dccc4b00c30959ad00e95bb0b75b6ef0
Author: Vadim Zeitlin <[email protected]>
Date:   Fri Jul 24 15:43:53 2015 +0200

    Don't set status of folders with empty MP_FTREE_FORMAT on startup.
    
    We ignore changes to the status of these folders when the number of messages
    in them changes later, but if we still set their status on startup, this can
    result in inconsistent folder status, e.g. if a "Trash" folder (which is a
    typical example of something you don't want to count messages in and so set
    MP_FTREE_FORMAT to empty string for it) initially has any unread messages and
    then is opened and cleared, it would still keep its "unread" colour.
    
    To avoid this, while still not having to recount messages in the folder
    whenever their number changes, don't set the status on startup neither. This
    is not perfect, especially as it's still possible to get into inconsistent
    state if the folder option is changed, but at least this state won't survive
    after the program restart now.

diff --git a/src/gui/wxFolderTree.cpp b/src/gui/wxFolderTree.cpp
index a5124f5..7b73266 100644
--- a/src/gui/wxFolderTree.cpp
+++ b/src/gui/wxFolderTree.cpp
@@ -1329,7 +1329,13 @@ wxFolderTreeNode::wxFolderTreeNode(wxTreeCtrl *tree,
    String fullname = folder->GetFullName();
 
    MailFolderStatus status;
-   bool hasStatus = MfStatusCache::Get()->GetStatus(fullname, &status);
+
+   // don't bother getting status for which we don't show the status in the
+   // tree anyhow
+   Profile_obj profile(folder->GetProfile());
+   const bool
+      hasStatus = !READ_CONFIG_TEXT(profile, MP_FTREE_FORMAT).empty()
+                     && MfStatusCache::Get()->GetStatus(fullname, &status);
 
    int image = GetFolderIconForDisplay(folder);
 

commit 22d1032ea35e311a7bee5815c21ab17c4f90d106
Author: Vadim Zeitlin <[email protected]>
Date:   Wed Mar 11 01:13:23 2015 +0100

    Allow overriding the attachment names directly in the file picker.
    
    Make it simpler to change the attachment names in the message by allowing to
    specify them directly in the file open dialog, instead of having to do it in a
    subsequent attachment properties dialog (or, worse, have to specially open it
    if it was disabled).

diff --git a/CHANGES b/CHANGES
index 4805c3a..adeb7f4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -11,6 +11,7 @@ Release 0.68 'Cynthia' September xx, 2010
 
 2015-08-28 NB: Removed "Browser is Netscape" and "Open in new window" and
                   added "Open in another browser" instead
+2015-03-11 VZ: Make it simpler to specify the attachment names in the message.
 2012-07-28 VZ: Optionally use popup notifications for new mail reporting.
 2012-07-21 VZ: Make it possible to set base mailbox path in the GUI.
 2011-12-26 VZ: Allow to create and configure new folders in "Quick filter".
diff --git a/src/gui/wxComposeView.cpp b/src/gui/wxComposeView.cpp
index 18892ab..644b2cb 100644
--- a/src/gui/wxComposeView.cpp
+++ b/src/gui/wxComposeView.cpp
@@ -4434,6 +4434,92 @@ wxComposeView::InsertMimePart(const MimePart *mimePart)
    }
 }
 
+namespace
+{
+
+// Helper class taking care of creating an additional text control in
+// wxFileDialog and returning its contents.
+class AttachNamesInFileDialog
+{
+public:
+   explicit AttachNamesInFileDialog(wxFileDialog& dialog)
+   {
+      ms_attachName = this;
+
+      m_text = NULL;
+
+      dialog.SetExtraControlCreator(Create);
+   }
+
+   static wxWindow* Create(wxWindow* parent)
+   {
+      wxCHECK( ms_attachName, NULL );
+
+      return ms_attachName->DoCreate(parent);
+   }
+
+   virtual ~AttachNamesInFileDialog()
+   {
+      ms_attachName = NULL;
+   }
+
+   wxArrayString GetNames() const
+   {
+      return wxSplit(m_names, ' ');
+   }
+
+private:
+   wxWindow *DoCreate(wxWindow* parent)
+   {
+      wxPanel* const panel = new wxPanel(parent);
+
+      // Currently we just use a single text control. This is fine for a single
+      // attachment but not so great for multiple ones (when the user is
+      // supposed to enter space-separated names manually and use backslash to
+      // escape any spaces inside the names), however it's not obvious how
+      // could this be improved as we don't get any notifications about the
+      // change in the number of the selected files from wx.
+
+      wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
+
+#ifdef OS_WIN
+      // At least under MSW things look better indented a bit.
+      sizer->AddSpacer(10);
+#endif // OS_WIN
+
+      sizer->Add(new wxStaticText(panel, wxID_ANY,
+                                  "Optional attachment name overriding file name:"),
+                 wxSizerFlags().Centre().Border());
+
+      m_text = new wxTextCtrl(panel, wxID_ANY, wxString(),
+                              wxDefaultPosition,
+                              wxSize(40*panel->GetCharWidth(), -1));
+      m_text->SetHint(_("attachment name in the message"));
+
+      sizer->Add(m_text, wxSizerFlags(1).Centre().Border());
+
+      panel->SetSizerAndFit(sizer);
+
+      // We need to bind to this event to update m_names immediately as m_text
+      // can't be used any more once the dialog is closed.
+      m_text->Bind(wxEVT_TEXT,
+                   [=](wxCommandEvent&) { m_names = m_text->GetValue(); });
+
+      return panel;
+   }
+
+   wxTextCtrl* m_text;
+   wxString m_names;
+
+   // The unique (because we can only be used from the main thread and the file
+   // dialog is not reentrant) object being currently used.
+   static AttachNamesInFileDialog* ms_attachName;
+};
+
+AttachNamesInFileDialog* AttachNamesInFileDialog::ms_attachName = NULL;
+
+} // anonymous namespace
+
 void wxComposeView::LetUserAddAttachment()
 {
    // Read the name of the directory used the last time. The name of the last
@@ -4474,6 +4560,8 @@ void wxComposeView::LetUserAddAttachment()
                   wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST
                 );
 
+   AttachNamesInFileDialog attachNames(dialog);
+
    if ( dialog.ShowModal() != wxID_OK )
    {
       // Dialog cancelled by user.
@@ -4492,10 +4580,12 @@ void wxComposeView::LetUserAddAttachment()
    wxArrayString filenames;
    dialog.GetPaths(filenames);
 
+   const wxArrayString names = attachNames.GetNames();
+
    const size_t nFiles = filenames.size();
    for ( size_t n = 0; n < nFiles; n++ )
    {
-      InsertFile(filenames[n]);
+      InsertFile(filenames[n], NULL, n < names.size() ? names[n] : wxString());
    }
 }
 

commit 5f7fb05fd392f2f952241db8d4337bc9dc6aaae9
Author: Vadim Zeitlin <[email protected]>
Date:   Wed Mar 11 00:59:21 2015 +0100

    Remember attachment directories on a per folder basis.
    
    Instead of having one global option, remember the directory used for selecting
    the file to attach on a per-folder basis, as this seems more useful: different
    directories would be typically used when writing to different recipients.
    
    Also don't remember the name of the attachment at all, this doesn't seem to be
    useful in practice as the same file is unlikely to be attached twice.

diff --git a/src/gui/wxComposeView.cpp b/src/gui/wxComposeView.cpp
index 9fbe295..18892ab 100644
--- a/src/gui/wxComposeView.cpp
+++ b/src/gui/wxComposeView.cpp
@@ -88,6 +88,7 @@
 #include "mail/Header.h"
 #include "mail/MimeDecode.h"
 
+#include "ConfigSourcesAll.h"
 #include "TemplateDialog.h"
 #include "AttachDialog.h"
 #include "MFolder.h"
@@ -4435,17 +4436,63 @@ wxComposeView::InsertMimePart(const MimePart *mimePart)
 
 void wxComposeView::LetUserAddAttachment()
 {
+   // Read the name of the directory used the last time. The name of the last
+   // attached file doesn't seem to be important as it would be rarely useful
+   // to attach the same file twice -- but it is common to attach files from
+   // the same directory as the last time.
+   static const char* const SETTINGS_PATH = "/Settings/FilePrompts";
+   static const char* const ATTACHMENT_DIR_KEY = "MsgInsertPath";
+
+   wxConfigBase* const config = AllConfigSources::Get().GetLocalConfig();
+   wxCHECK_RET( config, wxS("no local config?") );
+
+   // Try to use the value specific to the associated folder, falling back to
+   // its parent recursively as usual.
+   const wxString folderPath = m_Profile->GetFolderName();
+   config->SetPath(wxString::Format("%s/%s", SETTINGS_PATH, folderPath));
+
+   wxString dir;
+   for ( ;; )
+   {
+      if ( config->Read(ATTACHMENT_DIR_KEY, &dir) )
+         break;
+
+      if ( config->GetPath() == SETTINGS_PATH )
+         break;
+
+      config->SetPath("..");
+   }
+
+
+   // Now show the dialog to the user.
+   wxFileDialog dialog
+                (
+                  this,
+                  _("Please choose files to insert."),
+                  dir, wxString(),
+                  wxGetTranslation(wxALL_FILES),
+                  wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST
+                );
+
+   if ( dialog.ShowModal() != wxID_OK )
+   {
+      // Dialog cancelled by user.
+      return;
+   }
+
+   config->Write(wxString::Format
+                           (
+                              "%s/%s/%s",
+                              SETTINGS_PATH, folderPath, ATTACHMENT_DIR_KEY
+                           ),
+                 dialog.GetDirectory());
+
+
+   // Finally do attach the files.
    wxArrayString filenames;
-   size_t nFiles = wxPFilesSelector
-                   (
-                    filenames,
-                    _T("MsgInsert"),
-                    _("Please choose files to insert."),
-                    NULL, _T("dead.letter"), NULL,
-                    wxGetTranslation(wxALL_FILES),
-                    wxFD_OPEN | wxFD_FILE_MUST_EXIST,
-                    this
-                   );
+   dialog.GetPaths(filenames);
+
+   const size_t nFiles = filenames.size();
    for ( size_t n = 0; n < nFiles; n++ )
    {
       InsertFile(filenames[n]);

commit 2b5067fe9dd2bb5620b7786aff879e1b0405b728
Author: Vadim Zeitlin <[email protected]>
Date:   Tue Mar 10 21:58:29 2015 +0100

    Remove the unused strutil_path_{parent,filename}() functions.
    
    These functions were never used nor tested, just drop them.

diff --git a/include/strutil.h b/include/strutil.h
index 0b96f2c..91c905f 100644
--- a/include/strutil.h
+++ b/include/strutil.h
@@ -179,30 +179,6 @@ char *strutil_strsep(char **stringp, const char *delim);
 String
 strutil_expandfoldername(const String &name, MFolderType ftype = MF_FILE);
 
-#ifdef OS_UNIX
-#   define STRUTIL_PATH_SEPARATOR '/'
-#else
-#   define STRUTIL_PATH_SEPARATOR '\\'
-#endif
-
-/** Cut off last directory from path and return string before that.
-
-    @param pathname the path in which to go up
-    @param separator the path separator
-    @return the parent directory to the one specified
-*/
-String
-strutil_path_parent(String const &path, wxChar separator = STRUTIL_PATH_SEPARATOR);
-
-/** Cut off last name from path and return string that (filename).
-
-    @param pathname the path
-    @param separator the path separator
-    @return the parent directory to the one specified
-*/
-String
-strutil_path_filename(String const &path, wxChar separator = STRUTIL_PATH_SEPARATOR);
-
 /** Compare 2 filenames and return true if they refer to the same file. Notice
     that the files don't have to exist when this function is called.
 */
diff --git a/src/util/strutil.cpp b/src/util/strutil.cpp
index 8994c2e..f4ee6ea 100644
--- a/src/util/strutil.cpp
+++ b/src/util/strutil.cpp
@@ -458,39 +458,6 @@ strutil_expandpath(const String &ipath)
       return ipath;
 }
 
-/** Cut off last directory from path and return string before that.
-
-    @param pathname the path in which to go up
-    @param separator the path separator
-    @return the parent directory to the one specified
-*/
-String
-strutil_path_parent(String const &path, wxChar separator)
-{
-   const wxChar *cptr = wxStrrchr(path.c_str(),separator);
-   if(cptr == NULL) // not found
-      return wxEmptyString;
-
-   return path.Left(cptr - path.c_str());
-}
-
-/** Cut off last name from path and return string that (filename).
-
-    @param pathname the path
-    @param separator the path separator
-    @return the parent directory to the one specified
-*/
-String
-strutil_path_filename(String const &path, wxChar separator)
-{
-   const wxChar *cptr = wxStrrchr(path.c_str(),separator);
-   if(cptr == NULL) // not found
-      return wxEmptyString;
-
-   return String(cptr+1);
-}
-
-
 
 bool
 strutil_enforceCRLF(unsigned char *out, size_t outLen, const unsigned char *in)

commit 7df5a8c35e145afcc870955be21a7e7e3451bed8
Author: Vadim Zeitlin <[email protected]>
Date:   Tue Mar 10 21:48:14 2015 +0100

    Ignore the generated message catalog files.

diff --git a/locale/.gitignore b/locale/.gitignore
new file mode 100644
index 0000000..cd1f2c9
--- /dev/null
+++ b/locale/.gitignore
@@ -0,0 +1 @@
+*.mo

commit b5028fa6b41abd67bccbd422d5bf2cc5177a5781
Author: Vadim Zeitlin <[email protected]>
Date:   Tue Mar 10 21:45:30 2015 +0100

    Change Composer::InsertFile() to allow passing the attachment name.
    
    Also don't say that the filename can be NULL because it can't, it doesn't make
    much sense and there is an assert checking for this.

diff --git a/include/Composer.h b/include/Composer.h
index d289bf6..31f3a3a 100644
--- a/include/Composer.h
+++ b/include/Composer.h
@@ -273,12 +273,13 @@ public:
    virtual void Launch() = 0;
 
    /** insert a file into buffer
-       @param filename file to insert (ask the user if NULL)
+       @param filename file to insert (must be valid)
        @param mimetype mimetype to use (auto detect if NULL)
-       @param num_mimetype numeric mimetype
+       @param name name in the attachment (same as file name if NULL)
     */
-   virtual void InsertFile(const wxChar *filename = NULL,
-                           const wxChar *mimetype = NULL) = 0;
+   virtual void InsertFile(const wxChar *filename,
+                           const wxChar *mimetype = NULL,
+                           const wxChar *name     = NULL) = 0;
 
    /** Insert MIME content data
        @param data pointer to data (we will free() it later)
diff --git a/include/gui/wxComposeView.h b/include/gui/wxComposeView.h
index f5f9768..83b6bc9 100644
--- a/include/gui/wxComposeView.h
+++ b/include/gui/wxComposeView.h
@@ -144,8 +144,9 @@ public:
    // implement Composer pure virtuals
    virtual void InitText(Message *msg = NULL, const MessageView *msgview = NULL);
    virtual void Launch();
-   virtual void InsertFile(const wxChar *filename = NULL,
-                           const wxChar *mimetype = NULL);
+   virtual void InsertFile(const wxChar *filename,
+                           const wxChar *mimetype = NULL,
+                           const wxChar *name     = NULL);
 
    virtual void InsertData(void *data,
                            size_t length,
diff --git a/src/gui/wxComposeView.cpp b/src/gui/wxComposeView.cpp
index fc9894c..9fbe295 100644
--- a/src/gui/wxComposeView.cpp
+++ b/src/gui/wxComposeView.cpp
@@ -4185,7 +4185,9 @@ wxComposeView::InsertData(void *data,
 
 // insert file data
 void
-wxComposeView::InsertFile(const wxChar *fileName, const wxChar *mimetype)
+wxComposeView::InsertFile(const wxChar *fileName,
+                          const wxChar *mimetype,
+                          const wxChar *name)
 {
    CHECK_RET( !strutil_isempty(fileName), _T("filename can't be empty") );
 
@@ -4212,7 +4214,10 @@ wxComposeView::InsertFile(const wxChar *fileName, const wxChar *mimetype)
 
    AttachmentProperties props;
    props.filename = filename;
-   props.name = wxFileNameFromPath(filename);
+   if ( !strutil_isempty(name) )
+      props.name = name;
+   else
+      props.name = wxFileNameFromPath(filename);
    props.mimetype = strMimeType;
    mc->SetFile(props.filename);
    mc->SetName(props.name);

commit ab067521f4bc5e0e63262bd175076875d1c7b136
Author: Vadim Zeitlin <[email protected]>
Date:   Tue Mar 10 21:30:10 2015 +0100

    Switch to the already running external editor if possible.
    
    Use the recently added wxProcess::Activate() to activate the already running
    external editor and only tell the user to do it himself if we can't do it
    automatically -- this is a big gain in usability in practice.

diff --git a/src/gui/wxComposeView.cpp b/src/gui/wxComposeView.cpp
index 17e416e..fc9894c 100644
--- a/src/gui/wxComposeView.cpp
+++ b/src/gui/wxComposeView.cpp
@@ -3928,8 +3928,20 @@ bool wxComposeView::StartExternalEditor()
 {
    if ( m_procExtEdit )
    {
-      wxLogError(_("External editor is already running (PID %d)"),
-                 m_pidEditor);
+#if wxCHECK_VERSION(3, 1, 0)
+      // Try to switch to the already running editor automatically.
+      if ( m_procExtEdit->Activate() )
+      {
+         wxLogStatus(_("Switch to the already running editor (PID %d)"),
+                     m_pidEditor);
+      }
+      else
+#endif // wx 3.1+
+      {
+         // And fall back to telling the user to do it manually if this failed.
+         wxLogError(_("External editor is already running (PID %d)"),
+                    m_pidEditor);
+      }
 
       // ext editor is running
       return true;

commit 48bb1e9be3051694a616a19836cf038eb858d145
Author: Vadim Zeitlin <[email protected]>
Date:   Tue Mar 10 20:26:50 2015 +0100

    Require at least wxWidgets 3.0.0.
    
    The code probably doesn't even compile with the earlier wxWidgets versions by
    now and definitely is not tested with them, so just require 3.0.

diff --git a/include/Mconfig.h b/include/Mconfig.h
index 246861a..c8ea138 100644
--- a/include/Mconfig.h
+++ b/include/Mconfig.h
@@ -129,8 +129,8 @@
 // wxWindows stuff
 // ----------------------------------------------------------------------------
 
-#if !wxCHECK_VERSION(2, 9, 1)
-#  error "This version of Mahogany requires wxWidgets 2.9.1 or higher."
+#if !wxCHECK_VERSION(3, 0, 0)
+#  error "This version of Mahogany requires wxWidgets 3.0 or higher."
 #endif
 
 #ifdef USE_THREADS

commit e72f06994b868b50f16b56a9495410455f69caf1
Author: Vadim Zeitlin <[email protected]>
Date:   Wed Mar 4 00:36:29 2015 +0100

    Don't set user-unsettable headers in the message being sent out.
    
    Headers such as "Date" or "Message-ID" are generated automatically and
    shouldn't be set by user. And while this shouldn't happen any more now that
    the bug with not filtering out "Date" when editing an existing message was
    fixed in wxComposeView, still check for this just in case.

diff --git a/src/mail/SendMessageCC.cpp b/src/mail/SendMessageCC.cpp
index 2e29e5c..cc88344 100644
--- a/src/mail/SendMessageCC.cpp
+++ b/src/mail/SendMessageCC.cpp
@@ -1323,6 +1323,15 @@ SendMessageCC::Build(bool forStorage)
          return false;
       }
 
+      if ( !name.CanBeSetByUser() )
+      {
+         // We shouldn't be getting such headers at all here, but if we somehow
+         // do, ignore them.
+         wxLogDebug("Ignoring the value of not user-settable header \"%s\"",
+                    i->m_name);
+         continue;
+      }
+
       const wxCharBuffer value(MIME::EncodeHeader(i->m_value));
       if ( !value )
       {

commit e7ad321374e3a0fde9d1e27cc5129eba46cc3f68
Author: Vadim Zeitlin <[email protected]>
Date:   Wed Mar 4 00:34:51 2015 +0100

    Factor out mail message header names checks into a separate class.
    
    Don't duplicate almost the same IsValidHeaderName() function between
    wxHeadersDialogs and SendMessageCC code but reuse HeaderName::IsValid().
    Similarly replace the checks in wxComposeView and SendMessageCC with
    CanBeSetByUser() method of the new HeaderName class.

diff --git a/M.vcxproj b/M.vcxproj
index fed4624..f472f27 100644
--- a/M.vcxproj
+++ b/M.vcxproj
@@ -1411,6 +1411,7 @@
     <ClInclude Include="include\MailFolder.h" />

     <ClInclude Include="include\MailFolderCC.h" />

     <ClInclude Include="include\MailFolderCmn.h" />

+    <ClInclude Include="include\mail\Header.h" />

     <ClInclude Include="include\MApplication.h" />

     <ClInclude Include="include\MAtExit.h" />

     <ClInclude Include="include\gui\MBookCtrl.h" />

diff --git a/M.vcxproj.filters b/M.vcxproj.filters
index 9138a80..a6914e2 100644
--- a/M.vcxproj.filters
+++ b/M.vcxproj.filters
@@ -934,6 +934,9 @@
     <ClInclude Include="include\XFace.h">

       <Filter>Header Files</Filter>

     </ClInclude>

+    <ClInclude Include="include\mail\Header.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

   </ItemGroup>

   <ItemGroup>

     <ResourceCompile Include="res\M.rc">

diff --git a/include/mail/Header.h b/include/mail/Header.h
new file mode 100644
index 0000000..237a635
--- /dev/null
+++ b/include/mail/Header.h
@@ -0,0 +1,92 @@
+///////////////////////////////////////////////////////////////////////////////
+// Project:     M
+// File name:   mail/Header.h
+// Purpose:     Helpers for working with email messages headers
+// Author:      Vadim Zeitlin
+// Created:     2015-03-04
+// Copyright:   (c) 2015 Vadim Zeitlin <[email protected]>
+// Licence:     M license
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef M_MAIL_HEADER_H_
+#define M_MAIL_HEADER_H_
+
+#include <wx/string.h>
+
+/**
+    Class representing an email message header name.
+ */
+class HeaderName
+{
+public:
+   /**
+       Constructor from wxString.
+    */
+   explicit HeaderName(const wxString& name)
+      : m_name(name)
+   {
+      ASSERT( !name.empty() );
+   }
+
+   /**
+       Compare this header name with the given string.
+    */
+   bool operator==(const char* name) const
+   {
+      return m_name.CmpNoCase(name) == 0;
+   }
+
+   bool operator!=(const char* name) const
+   {
+      return !(*this == name);
+   }
+
+   /**
+       Checks if this is a valid header name conforming to RFC 2822.
+
+       @return empty string if the name is valid, otherwise the string contains
+          the user readable explanation of why it isn't.
+    */
+   wxString IsValid() const
+   {
+      for ( wxString::const_iterator p = m_name.begin(); p != m_name.end(); ++p )
+      {
+         // RFC 822 allows '/' but we don't because it has a special meaning for
+         // the profiles/wxConfig; other characters are excluded in accordance
+         // with the definition of the header name in the section 2.2 of RFC 2822
+         wxChar c = *p;
+         if ( c < 32 || c > 126 )
+            return _("only ASCII characters are allowed");
+
+         if ( c == ':' )
+            return _("colons are not allowed");
+      }
+
+      return wxString();
+   }
+
+   /**
+       Check if this header can be set by user.
+
+       Some headers are always generated by the program and setting them
+       explicitly can't be allowed as this would result in duplicate headers in
+       the outgoing message and a lot of confusion.
+    */
+   bool CanBeSetByUser() const
+   {
+      return *this != "DATE" &&
+             *this != "DELIVERED-TO" &&
+             *this != "CONTENT-TYPE" &&
+             *this != "CONTENT-DISPOSITION" &&
+             *this != "CONTENT-TRANSFER-ENCODING" &&
+             *this != "MESSAGE-ID" &&
+             *this != "MIME-VERSION" &&
+             *this != "RECEIVED" &&
+             *this != "RETURN-PATH";
+   }
+
+private:
+   const wxString m_name;
+};
+
+#endif // M_MAIL_HEADER_H_
diff --git a/src/gui/wxComposeView.cpp b/src/gui/wxComposeView.cpp
index 9152adb..17e416e 100644
--- a/src/gui/wxComposeView.cpp
+++ b/src/gui/wxComposeView.cpp
@@ -85,6 +85,7 @@
 
 #include "adb/AdbManager.h"
 
+#include "mail/Header.h"
 #include "mail/MimeDecode.h"
 
 #include "TemplateDialog.h"
@@ -1896,43 +1897,26 @@ Composer::EditMessage(Profile *profile, Message *msg)
 
    cv->ResetDirty();
 
-   // finally, also import all headers except the ones in ignoredHeaders:
-   //
-   // first ignore those which are generated by the transport layer as it
-   // doesn't make sense to generate them at all a MUA
-   wxSortedArrayString ignoredHeaders;
-   ignoredHeaders.Add(_T("RECEIVED"));
-   ignoredHeaders.Add(_T("RETURN-PATH"));
-   ignoredHeaders.Add(_T("DELIVERED-TO"));
-
-   // second, ignore some headers which we always generate ourselves and don't
-   // allow the user to override anyhow
-   ignoredHeaders.Add(_T("DATE"));
-   ignoredHeaders.Add(_T("MESSAGE-ID"));
-   ignoredHeaders.Add(_T("MIME-VERSION"));
-   ignoredHeaders.Add(_T("CONTENT-TYPE"));
-   ignoredHeaders.Add(_T("CONTENT-DISPOSITION"));
-   ignoredHeaders.Add(_T("CONTENT-TRANSFER-ENCODING"));
-
+   // finally, also import headers
    wxString nameWithCase, value;
    HeaderIterator hdrIter = msg->GetHeaderIterator();
    while ( hdrIter.GetNext(&nameWithCase, &value) )
    {
-      wxString name = nameWithCase.Upper();
+      const HeaderName name(nameWithCase);
       value = MIME::DecodeHeader(value);
 
       // test for some standard headers which need special treatment
-      if ( name == _T("SUBJECT") )
+      if ( name == "Subject" )
          cv->SetSubject(value);
-      else if ( name == _T("FROM") )
+      else if ( name == "From" )
          cv->SetFrom(value);
-      else if ( name == _T("TO") )
+      else if ( name == "To" )
          cv->AddTo(value);
-      else if ( name == _T("CC") )
+      else if ( name == "CC" )
          cv->AddCc(value);
-      else if ( name == _T("BCC") )
+      else if ( name == "BCC" )
          cv->AddBcc(value);
-      else if ( name == _T("FCC") )
+      else if ( name == "FCC" )
       {
          // if we have any FCC recipients, they should replace the default ones
          // instead of being appended to them as then the default recipients
@@ -1941,7 +1925,7 @@ Composer::EditMessage(Profile *profile, Message *msg)
 
          cv->AddFcc(value);
       }
-      else if ( ignoredHeaders.Index(name) == wxNOT_FOUND )
+      else if ( name.CanBeSetByUser() )
       {
          // compare case sensitively here as we always write HEADER_IS_DRAFT in
          // the same case
diff --git a/src/gui/wxHeadersDialogs.cpp b/src/gui/wxHeadersDialogs.cpp
index 4d1490c..02d242e 100644
--- a/src/gui/wxHeadersDialogs.cpp
+++ b/src/gui/wxHeadersDialogs.cpp
@@ -59,6 +59,8 @@
 
 #include "gui/wxSelectionDlg.h"
 
+#include "mail/Header.h"
+
 #include "HeadersDialogs.h"
 
 // ----------------------------------------------------------------------------
@@ -110,51 +112,6 @@ enum
 };
 
 // ----------------------------------------------------------------------------
-// private functions
-// ----------------------------------------------------------------------------
-
-namespace
-{
-
-/**
-   Checks if the given string is a valid header name conforming to RFC 2822.
-
-   @param header The string to check.
-   @param reason If non-NULL, filled with the explanation of why the header
-                 name is invalid if the function returns false.
-   @return true if the header name is valid, false otherwise
- */
-bool IsValidHeaderName(const wxString& header, wxString *reason)
-{
-   for ( wxString::const_iterator p = header.begin(); p != header.end(); ++p )
-   {
-      // RFC 822 allows '/' but we don't because it has a special meaning for
-      // the profiles/wxConfig; other characters are excluded in accordance
-      // with the definition of the header name in the section 2.2 of RFC 2822
-      wxChar c = *p;
-      if ( c < 32 || c > 126 )
-      {
-         if ( reason )
-            *reason = "only ASCII characters are allowed";
-
-         return false;
-      }
-
-      if ( c == ':' )
-      {
-         if ( reason )
-            *reason = "colons are not allowed";
-
-         return false;
-      }
-   }
-
-   return true;
-}
-
-} // anonymous namespace
-
-// ----------------------------------------------------------------------------
 // private classes
 // ----------------------------------------------------------------------------
 
@@ -569,11 +526,11 @@ bool wxMsgViewHeadersDialog::OnItemAdd(const wxString& item)
    if ( !wxSelectionsOrderDialog::OnItemAdd(item) )
       return false;
 
-   wxString reason;
-   if ( !IsValidHeaderName(item, &reason) )
+   const wxString headerErr = HeaderName(item).IsValid();
+   if ( !headerErr.empty() )
    {
       wxLogWarning(_("\"%s\" is not a valid header name: %s."),
-                   item.c_str(), reason.c_str());
+                   item, headerErr);
 
       return false;
    }
@@ -828,14 +785,14 @@ bool wxCustomHeaderDialog::TransferDataFromWindow()
    m_headerName = m_textctrlName->GetValue();
 
    // check that this is a valid header name
-   wxString reason;
-   if ( IsValidHeaderName(m_headerName, &reason) )
+   wxString reason = HeaderName(m_headerName).IsValid();
+   if ( reason.empty() )
    {
       // in addition to the standard RFC checks we also forbid slashes as this
       // string is used as profile key
       if ( m_headerName.find('/') != wxString::npos )
       {
-         reason = "slashes are not allowed in this context";
+         reason = _("slashes are not allowed in this context");
       }
    }
 
diff --git a/src/mail/SendMessageCC.cpp b/src/mail/SendMessageCC.cpp
index 5e0f569..2e29e5c 100644
--- a/src/mail/SendMessageCC.cpp
+++ b/src/mail/SendMessageCC.cpp
@@ -40,6 +40,7 @@
 #include "Message.h"
 #include "MFolder.h"
 #include "mail/Driver.h"
+#include "mail/Header.h"
 
 #ifdef OS_UNIX
 #  include "sysutil.h"
@@ -144,34 +145,6 @@ bool IsAddressHeader(const String& name)
           name == "BCC";
 }
 
-// test if we allow this header to be set by user
-//
-// NB: the header name must be in upper case
-inline
-bool HeaderCanBeSetByUser(const String& name)
-{
-   return name != "MIME-VERSION" &&
-          name != "CONTENT-TYPE" &&
-          name != "CONTENT-DISPOSITION" &&
-          name != "CONTENT-TRANSFER-ENCODING" &&
-          name != "MESSAGE-ID";
-}
-
-// check if the header name is valid (as defined in 2.2 of RFC 2822)
-bool IsValidHeaderName(const char *name)
-{
-   if ( !name )
-      return false;
-
-   for ( ; *name; name++ )
-   {
-      if ( *name >= 127 || iscntrl(*name) )
-         return false;
-   }
-
-   return true;
-}
-
 // create a new BODY parameter and initialize it
 PARAMETER *CreateBodyParameter(const char *name, const char *value)
 {
@@ -1081,7 +1054,7 @@ SendMessageCC::AddHeaderEntry(const String& nameIn, const String& value)
    {
       FAIL_MSG( "Address headers not supported here, use SetFrom() &c!" );
    }
-   else if ( !HeaderCanBeSetByUser(name) )
+   else if ( !HeaderName(name).CanBeSetByUser() )
    {
       ERRORMESSAGE((_("The value of the header '%s' cannot be modified."),
                     nameIn.c_str()));
@@ -1341,12 +1314,12 @@ SendMessageCC::Build(bool forStorage)
          i != m_extraHeaders.end();
          ++i )
    {
-      const wxWX2MBbuf name(i->m_name.To8BitData());
-      if ( !IsValidHeaderName(name) )
+      const HeaderName name(i->m_name);
+      const wxString headerErr = name.IsValid();
+      if ( !headerErr.empty() )
       {
-         wxLogError(_("Custom header name \"%s\" is invalid, please use only "
-                      "printable ASCII characters in the header names."),
-                    i->m_name.c_str());
+         wxLogError(_("Custom header name \"%s\" is invalid: %s."),
+                    i->m_name, headerErr);
          return false;
       }
 
@@ -1359,13 +1332,15 @@ SendMessageCC::Build(bool forStorage)
          return false;
       }
 
-      if ( wxStricmp(name, "Reply-To") == 0 )
+      if ( name == "Reply-To" )
          replyToSet = true;
-      else if ( wxStricmp(name, "X-Mailer") == 0 )
+      else if ( name == "X-Mailer" )
          xmailerSet = true;
 
 
-      m_headerNames[h] = strutil_strdup(name);
+      // Conversion to ASCII is safe because HeaderName::IsValid() would have
+      // returned false if we had any non-ASCII characters in the name.
+      m_headerNames[h] = strutil_strdup(i->m_name.ToAscii());
       m_headerValues[h] = strutil_strdup(value);
 
       h++;

commit 583f9e9d51b55c5715593995373b6e88a22d9e7f
Author: Vadim Zeitlin <[email protected]>
Date:   Wed Mar 4 00:24:56 2015 +0100

    Don't take "Date" header from the original message when editing it.
    
    This results in having duplicate "Date" headers in the message being sent out
    as a "Date" header is also always generated when sending which is at best
    confusing and at worst results in the message appearing to have a wrong date.

diff --git a/src/gui/wxComposeView.cpp b/src/gui/wxComposeView.cpp
index 1cfc643..9152adb 100644
--- a/src/gui/wxComposeView.cpp
+++ b/src/gui/wxComposeView.cpp
@@ -1907,6 +1907,7 @@ Composer::EditMessage(Profile *profile, Message *msg)
 
    // second, ignore some headers which we always generate ourselves and don't
    // allow the user to override anyhow
+   ignoredHeaders.Add(_T("DATE"));
    ignoredHeaders.Add(_T("MESSAGE-ID"));
    ignoredHeaders.Add(_T("MIME-VERSION"));
    ignoredHeaders.Add(_T("CONTENT-TYPE"));

-----------------------------------------------------------------------

Summary of changes:
 .gitignore                      |    1 +
 CHANGES                         |    1 +
 M.vcxproj                       |   25 +++--
 M.vcxproj.filters               |    3 +
 Mconfig.vcxproj                 |   11 +-
 doc/build_win.txt               |  110 +++++--------------
 include/Composer.h              |    9 +-
 include/MFStatus.h              |    2 +-
 include/Mconfig.h               |    4 +-
 include/gui/wxComposeView.h     |    5 +-
 include/mail/FolderPool.h       |    2 +-
 include/mail/Header.h           |   92 ++++++++++++++++
 include/strutil.h               |   24 ----
 lib/compface/compface.vcxproj   |   11 +-
 lib/dspam/dspam.vcxproj         |   11 +-
 lib/imap/imap.vcxproj           |   11 +-
 lib/imap/src/osdep/nt/env_nt.c  |    2 +-
 lib/imap/src/osdep/nt/mhnt.c    |    2 +-
 lib/imap/src/osdep/nt/yunchan.c |   47 --------
 lib/imap/src/osdep/nt/yunchan.h |    4 -
 lib/imap/src/osdep/unix/mh.c    |    2 +-
 locale/.gitignore               |    1 +
 locale/pouniq.pl                |    2 +-
 src/classes/ComposeTemplate.cpp |    2 +-
 src/gui/ClickURL.cpp            |    2 +-
 src/gui/wxComposeView.cpp       |  223 +++++++++++++++++++++++++++++++--------
 src/gui/wxFolderTree.cpp        |   65 ++++++------
 src/gui/wxHeadersDialogs.cpp    |   59 ++---------
 src/gui/wxTextDialog.cpp        |    2 +-
 src/gui/wxllist.cpp             |    2 +-
 src/gui/wxlwindow.cpp           |    2 +-
 src/mail/MailFolder.cpp         |    3 +-
 src/mail/SendMessageCC.cpp      |   58 ++++-------
 src/mail/ThreadJWZ.cpp          |    4 +-
 src/util/strutil.cpp            |   33 ------
 src/wx/vcard/versit.vcxproj     |   31 +-----
 36 files changed, 439 insertions(+), 429 deletions(-)
 create mode 100644 include/mail/Header.h
 create mode 100644 locale/.gitignore


hooks/post-receive
-- 
Mahogany sources repository.


--===============1561226580411846567==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
--===============1561226580411846567==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Mahogany-cvsupdates mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

--===============1561226580411846567==--