OSDN Git Service

Add /table-delimiter, /table-quote and /table-allownewlinesinquotes command line...
authorTakashi Sawanaka <sdottaka@users.sourceforge.net>
Sun, 18 Jul 2021 14:44:09 +0000 (23:44 +0900)
committerTakashi Sawanaka <sdottaka@users.sourceforge.net>
Sun, 18 Jul 2021 14:44:09 +0000 (23:44 +0900)
Docs/Manual/EN/Command_line.xml
Docs/Manual/JP/Command_line.xml
Src/MainFrm.cpp
Src/MainFrm.h
Src/Merge.cpp
Src/MergeCmdLineInfo.cpp
Src/MergeCmdLineInfo.h
Src/MergeDoc.cpp
Src/MergeDoc.h

index a77d2fd..cd0a63e 100644 (file)
@@ -76,6 +76,9 @@
       <arg choice="opt" rep="norepeat"><option>/l</option>
       <replaceable>linenumber</replaceable></arg>
 
+      <arg choice="opt" rep="norepeat"><option>/table-delimiter</option>
+      <replaceable>delimiter</replaceable></arg>
+
       <arg choice="opt" rep="norepeat"><option>/dl</option>
       <replaceable>leftdesc</replaceable></arg>
 
       <arg choice="opt" rep="norepeat"><option>/ignorecomments</option></arg>
 
       <arg choice="opt" rep="norepeat"><option>/unpacker</option>
-      <replaceable>unpacker name</replaceable></arg>
+      <replaceable>unpacker-name</replaceable></arg>
 
       <arg choice="opt" rep="norepeat"><option>/prediffer</option>
-      <replaceable>prediffer name</replaceable></arg>
+      <replaceable>prediffer-name</replaceable></arg>
 
       <arg choice="opt" rep="norepeat"><option>/cp</option>
       <replaceable>codepage</replaceable></arg>
     </varlistentry>
 
     <varlistentry>
+      <term><option>/table-delimiter <replaceable>delimiter</replaceable></option></term>
+      <listitem>
+        <para>Specifies a delimiter character for table editing.</para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
       <term><option>/dl</option></term>
       <listitem>
         <para>Specifies a description in the left side title
index 2d88f25..ba8398c 100644 (file)
@@ -76,6 +76,9 @@
       <arg choice="opt" rep="norepeat"><option>/l</option>
       <replaceable>linenumber</replaceable></arg>
 
+      <arg choice="opt" rep="norepeat"><option>/table-delimiter</option>
+      <replaceable>delimiter</replaceable></arg>
+
       <arg choice="opt" rep="norepeat"><option>/dl</option>
       <replaceable>leftdesc</replaceable></arg>
 
       <arg choice="opt" rep="norepeat"><option>/ignorecomments</option></arg>
 
       <arg choice="opt" rep="norepeat"><option>/unpacker</option>
-      <replaceable>unpacker name</replaceable></arg>
+      <replaceable>unpacker-name</replaceable></arg>
 
       <arg choice="opt" rep="norepeat"><option>/prediffer</option>
-      <replaceable>prediffer name</replaceable></arg>
+      <replaceable>prediffer-name</replaceable></arg>
 
       <arg choice="opt" rep="norepeat"><option>/cp</option>
       <replaceable>codepage</replaceable></arg>
     </varlistentry>
 
     <varlistentry>
+      <term><option>/table-delimiter <replaceable>delimiter</replaceable></option></term>
+      <listitem>
+        <para>テーブル編集用の区切り文字を指定します。</para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
       <term><option>/dl</option></term>
       <listitem>
         <para>左側タイトルバーの説明を指定します。
index 246258d..e885d60 100644 (file)
@@ -697,7 +697,7 @@ FileLocationGuessEncodings(FileLocation & fileloc, int iGuessEncoding)
 bool CMainFrame::ShowAutoMergeDoc(CDirDoc * pDirDoc,
        int nFiles, const FileLocation ifileloc[],
        const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
-       const PackingInfo * infoUnpacker /*= nullptr*/, int line /*= -1*/)
+       const PackingInfo * infoUnpacker /*= nullptr*/, OpenTextFileParams* pOpenParams /*= nullptr*/)
 {
        ASSERT(pDirDoc != nullptr);
 
@@ -726,22 +726,22 @@ bool CMainFrame::ShowAutoMergeDoc(CDirDoc * pDirDoc,
                else if (filterBin.includeFile(filepath) && CHexMergeView::IsLoadable())
                        return ShowHexMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
        }
-       return ShowTextOrTableMergeDoc({}, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, line);
+       return ShowTextOrTableMergeDoc({}, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, pOpenParams);
 }
 
 bool CMainFrame::ShowMergeDoc(UINT nID, CDirDoc* pDirDoc,
        int nFiles, const FileLocation ifileloc[],
        const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
-       const PackingInfo* infoUnpacker /*= nullptr*/, int line /*= -1*/)
+       const PackingInfo* infoUnpacker /*= nullptr*/, OpenTextFileParams* pOpenParams /*= nullptr*/)
 {
        switch (nID)
        {
        case ID_MERGE_COMPARE_TEXT:
                return ShowTextMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
-                       strDesc, sReportFile, infoUnpacker, line);
+                       strDesc, sReportFile, infoUnpacker, pOpenParams);
        case ID_MERGE_COMPARE_TABLE:
                return ShowTableMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
-                       strDesc, sReportFile, infoUnpacker, line);
+                       strDesc, sReportFile, infoUnpacker, pOpenParams);
        case ID_MERGE_COMPARE_HEX:
                return ShowHexMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
                        strDesc, sReportFile, infoUnpacker);
@@ -750,7 +750,7 @@ bool CMainFrame::ShowMergeDoc(UINT nID, CDirDoc* pDirDoc,
                        strDesc, sReportFile, infoUnpacker);
        default:
                return ShowAutoMergeDoc(pDirDoc, nFiles, ifileloc, dwFlags,
-                       strDesc, sReportFile, infoUnpacker, line);
+                       strDesc, sReportFile, infoUnpacker, pOpenParams);
        }
 }
 
@@ -789,7 +789,7 @@ int GetActivePaneFromFlags(int nFiles, const DWORD dwFlags[])
 bool CMainFrame::ShowTextOrTableMergeDoc(std::optional<bool> table, CDirDoc * pDirDoc,
        int nFiles, const FileLocation ifileloc[],
        const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
-       const PackingInfo * infoUnpacker /*= nullptr*/, int line /*= -1*/)
+       const PackingInfo * infoUnpacker /*= nullptr*/, OpenTextFileParams* pOpenParams /*= nullptr*/)
 {
        if (m_pMenus[MENU_MERGEVIEW] == nullptr)
                theApp.m_pDiffTemplate->m_hMenuShared = NewMergeViewMenu();
@@ -822,6 +822,14 @@ bool CMainFrame::ShowTextOrTableMergeDoc(std::optional<bool> table, CDirDoc * pD
        }
 
        pMergeDoc->SetEnableTableEditing(table);
+       if (pOpenParams && table.value_or(false))
+       {
+               CMergeDoc::TableProps props = CMergeDoc::GetTablePropertiesByFileName(fileloc[0].filepath, true, false);
+               props.delimiter = pOpenParams->m_tableDelimiter.value_or(props.delimiter);
+               props.quote = pOpenParams->m_tableQuote.value_or(props.quote);
+               props.allowNewlinesInQuotes = pOpenParams->m_tableAllowNewlinesInQuotes.value_or(props.allowNewlinesInQuotes);
+               pMergeDoc->SetTableProperties(props);
+       }
 
        // Note that OpenDocs() takes care of closing compare window when needed.
        bool bResult = pMergeDoc->OpenDocs(nFiles, fileloc, GetROFromFlags(nFiles, dwFlags).data(), strDesc);
@@ -853,7 +861,7 @@ bool CMainFrame::ShowTextOrTableMergeDoc(std::optional<bool> table, CDirDoc * pD
                }
        }
 
-       pMergeDoc->MoveOnLoad(GetActivePaneFromFlags(nFiles, dwFlags), line, true);
+       pMergeDoc->MoveOnLoad(GetActivePaneFromFlags(nFiles, dwFlags), pOpenParams ? pOpenParams->m_line : -1, true);
 
        if (!sReportFile.empty())
                pMergeDoc->GenerateReport(sReportFile);
@@ -864,17 +872,17 @@ bool CMainFrame::ShowTextOrTableMergeDoc(std::optional<bool> table, CDirDoc * pD
 bool CMainFrame::ShowTextMergeDoc(CDirDoc* pDirDoc,
        int nFiles, const FileLocation ifileloc[],
        const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
-       const PackingInfo* infoUnpacker /*= nullptr*/, int line /*= -1*/)
+       const PackingInfo* infoUnpacker /*= nullptr*/, OpenTextFileParams* pOpenParams /*= nullptr*/)
 {
-       return ShowTextOrTableMergeDoc(false, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, line);
+       return ShowTextOrTableMergeDoc(false, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, pOpenParams); 
 }
 
 bool CMainFrame::ShowTableMergeDoc(CDirDoc* pDirDoc,
        int nFiles, const FileLocation ifileloc[],
        const DWORD dwFlags[], const String strDesc[], const String& sReportFile /*= _T("")*/,
-       const PackingInfo* infoUnpacker /*= nullptr*/, int line /*= -1*/)
+       const PackingInfo* infoUnpacker /*= nullptr*/, OpenTextFileParams* pOpenParams /*= nullptr*/)
 {
-       return ShowTextOrTableMergeDoc(true, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, line);
+       return ShowTextOrTableMergeDoc(true, pDirDoc, nFiles, ifileloc, dwFlags, strDesc, sReportFile, infoUnpacker, pOpenParams);
 }
 
 bool CMainFrame::ShowHexMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
@@ -930,7 +938,7 @@ bool CMainFrame::ShowImgMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocati
 }
 
 bool CMainFrame::ShowTextMergeDoc(CDirDoc* pDirDoc, int nBuffers, const String text[],
-               const String strDesc[], const String& strFileExt, int line /*= -1*/)
+               const String strDesc[], const String& strFileExt, OpenTextFileParams* pOpenParams /*= nullptr*/)
 {
        FileLocation fileloc[3];
        DWORD dwFlags[3] = {};
@@ -949,7 +957,7 @@ bool CMainFrame::ShowTextMergeDoc(CDirDoc* pDirDoc, int nBuffers, const String t
                }
                fileloc[nBuffer].setPath(workFile);
        }
-       return ShowTextMergeDoc(pDirDoc2, nBuffers, fileloc, dwFlags, strDesc, _T(""), nullptr, line);
+       return ShowTextMergeDoc(pDirDoc2, nBuffers, fileloc, dwFlags, strDesc, _T(""), nullptr, pOpenParams);
 }
 
 /**
@@ -1067,7 +1075,7 @@ bool CMainFrame::DoFileOpen(const PathContext * pFiles /*= nullptr*/,
        const DWORD dwFlags[] /*= nullptr*/, const String strDesc[] /*= nullptr*/, const String& sReportFile /*= T("")*/,
        bool bRecurse /*= false*/, CDirDoc* pDirDoc/*= nullptr*/,
        const PackingInfo *infoUnpacker /*= nullptr*/, const PrediffingInfo *infoPrediffer /*= nullptr*/,
-       UINT nID /*= 0*/, int line /*= -1*/)
+       UINT nID /*= 0*/, OpenTextFileParams *pOpenParams /*= nullptr*/)
 {
        if (pDirDoc != nullptr && !pDirDoc->CloseMergeDocs())
                return false;
@@ -1195,7 +1203,7 @@ bool CMainFrame::DoFileOpen(const PathContext * pFiles /*= nullptr*/,
                }
 
                ShowMergeDoc(nID, pDirDoc, tFiles.GetSize(), fileloc, dwFlags, strDesc, sReportFile,
-                               infoUnpacker, line);
+                               infoUnpacker, pOpenParams);
        }
 
        if (pFiles != nullptr && (!dwFlags || !(dwFlags[0] & FFILEOPEN_NOMRU)))
@@ -1209,14 +1217,14 @@ bool CMainFrame::DoFileOpen(const PathContext * pFiles /*= nullptr*/,
 
 bool CMainFrame::DoFileOpen(UINT nID, const PathContext* pFiles /*= nullptr*/,
        const DWORD dwFlags[] /*= nullptr*/, const String strDesc[] /*= nullptr*/,
-       const String& sReportFile /*= _T("")*/, const PackingInfo *infoUnpacker /*= nullptr*/, int line /*= -1*/)
+       const String& sReportFile /*= _T("")*/, const PackingInfo *infoUnpacker /*= nullptr*/, OpenTextFileParams *pOpenParams /*= nullptr*/)
 {
        CDirDoc* pDirDoc = static_cast<CDirDoc*>(theApp.m_pDirTemplate->CreateNewDocument());
        FileLocation fileloc[3];
        for (int pane = 0; pane < pFiles->GetSize(); pane++)
                fileloc[pane].setPath((*pFiles)[pane]);
        return ShowMergeDoc(nID, pDirDoc, pFiles->GetSize(), fileloc,
-               dwFlags, strDesc, sReportFile, infoUnpacker, line);
+               dwFlags, strDesc, sReportFile, infoUnpacker, pOpenParams);
 }
 
 void CMainFrame::UpdateFont(FRAMETYPE frame)
@@ -2490,7 +2498,7 @@ bool CMainFrame::DoOpenConflict(const String& conflictFile, const String strDesc
 }
 
 bool CMainFrame::DoSelfCompare(UINT nID, const String& file, const String strDesc[] /*= nullptr*/,
-       const PackingInfo *infoUnpacker /*= nullptr*/, int line /*= -1*/)
+       const PackingInfo *infoUnpacker /*= nullptr*/, OpenTextFileParams *pOpenParams /*= nullptr*/)
 {
        String ext = paths::FindExtension(file);
        TempFilePtr wTemp(new TempFile());
@@ -2504,7 +2512,7 @@ bool CMainFrame::DoSelfCompare(UINT nID, const String& file, const String strDes
                (strDesc && !strDesc[1].empty()) ? strDesc[1] : _("") };
        DWORD dwFlags[2] = {FFILEOPEN_READONLY | FFILEOPEN_NOMRU, FFILEOPEN_NOMRU};
        PathContext tmpPathContext(copiedFile, file);
-       return DoFileOpen(nID, &tmpPathContext, dwFlags, strDesc2, _T(""), infoUnpacker, line);
+       return DoFileOpen(nID, &tmpPathContext, dwFlags, strDesc2, _T(""), infoUnpacker, pOpenParams);
 }
 
 /**
index 6d4cf00..f827b49 100644 (file)
@@ -69,6 +69,14 @@ public:
                FRAME_OTHER, /**< No frame? */
        };
 
+       struct OpenTextFileParams
+       {
+               int m_line = -1;
+               std::optional<TCHAR> m_tableDelimiter;
+               std::optional<TCHAR> m_tableQuote;
+               std::optional<bool> m_tableAllowNewlinesInQuotes;
+       };
+
        CMainFrame();
 
 // Attributes
@@ -93,27 +101,29 @@ public:
        bool DoFileOpen(const PathContext *pFiles = nullptr,
                const DWORD dwFlags[] = nullptr, const String strDesc[] = nullptr,
                const String& sReportFile = _T(""), bool bRecurse = false, CDirDoc *pDirDoc = nullptr,
-               const PackingInfo * infoUnpacker = nullptr, const PrediffingInfo * infoPrediffer = nullptr, UINT nID = 0, int line = -1);
+               const PackingInfo * infoUnpacker = nullptr, const PrediffingInfo * infoPrediffer = nullptr, UINT nID = 0, OpenTextFileParams *pOpenParams = nullptr);
        bool DoFileOpen(UINT nID, const PathContext* pFiles = nullptr,
                const DWORD dwFlags[] = nullptr, const String strDesc[] = nullptr,
-               const String& sReportFile = _T(""), const PackingInfo* infoUnpacker = nullptr, int line = -1);
+               const String& sReportFile = _T(""), const PackingInfo* infoUnpacker = nullptr, OpenTextFileParams *pOpenParams = nullptr);
+       bool DoOpenConflict(const String& conflictFile, const String strDesc[] = nullptr, bool checked = false);
+       bool DoSelfCompare(UINT nID, const String& file, const String strDesc[] = nullptr, const PackingInfo* infoUnpacker = nullptr, OpenTextFileParams* pOpenParams = nullptr);
        bool ShowAutoMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
                const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""),
-               const PackingInfo * infoUnpacker = nullptr, int line = -1);
+               const PackingInfo * infoUnpacker = nullptr, OpenTextFileParams *pOpenParams = nullptr);
        bool ShowMergeDoc(UINT nID, CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
                const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""),
-               const PackingInfo * infoUnpacker = nullptr, int line = -1);
+               const PackingInfo * infoUnpacker = nullptr, OpenTextFileParams *pOpenParams = nullptr);
        bool ShowTextOrTableMergeDoc(std::optional<bool> table, CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
                const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""),
-               const PackingInfo * infoUnpacker = nullptr, int line = -1);
+               const PackingInfo * infoUnpacker = nullptr, OpenTextFileParams *pOpenParams = nullptr);
        bool ShowTextMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
                const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""),
-               const PackingInfo * infoUnpacker = nullptr, int line = -1);
+               const PackingInfo * infoUnpacker = nullptr, OpenTextFileParams *pOpenParams = nullptr);
        bool ShowTextMergeDoc(CDirDoc* pDirDoc, int nBuffers, const String text[],
-               const String strDesc[], const String& strFileExt, int line = -1);
+               const String strDesc[], const String& strFileExt, OpenTextFileParams *pOpenParams = nullptr);
        bool ShowTableMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
                const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""),
-               const PackingInfo * infoUnpacker = nullptr, int line = -1);
+               const PackingInfo * infoUnpacker = nullptr, OpenTextFileParams *pOpenParams = nullptr);
        bool ShowHexMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
                const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""), const PackingInfo * infoUnpacker = nullptr);
        bool ShowImgMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
@@ -125,8 +135,6 @@ public:
        void SelectFilter();
        void StartFlashing();
        bool AskCloseConfirmation();
-       bool DoOpenConflict(const String& conflictFile, const String strDesc[] = nullptr, bool checked = false);
-       bool DoSelfCompare(UINT nID, const String& file, const String strDesc[] = nullptr, const PackingInfo* infoUnpacker = nullptr, int line = -1);
        static FRAMETYPE GetFrameType(const CFrameWnd * pFrame);
        static void UpdateDocTitle();
        static void ReloadMenu();
index 743abab..e3025ab 100644 (file)
@@ -712,6 +712,15 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF
                        strDesc[2] = cmdInfo.m_sRightDesc;
                }
 
+               CMainFrame::OpenTextFileParams openParams;
+               openParams.m_line = cmdInfo.m_nLineIndex;
+               if (cmdInfo.m_nWindowType == MergeCmdLineInfo::TABLE)
+               {
+                       openParams.m_tableDelimiter = cmdInfo.m_cTableDelimiter;
+                       openParams.m_tableQuote = cmdInfo.m_cTableQuote;
+                       openParams.m_tableAllowNewlinesInQuotes = cmdInfo.m_bTableAllowNewlinesInQuotes;
+               }
+
                if (cmdInfo.m_Files.GetSize() > 2)
                {
                        cmdInfo.m_dwLeftFlags |= FFILEOPEN_CMDLINE;
@@ -720,14 +729,14 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF
                        DWORD dwFlags[3] = {cmdInfo.m_dwLeftFlags, cmdInfo.m_dwMiddleFlags, cmdInfo.m_dwRightFlags};
                        bCompared = pMainFrame->DoFileOpen(&cmdInfo.m_Files,
                                dwFlags, strDesc, cmdInfo.m_sReportFile, cmdInfo.m_bRecurse, nullptr,
-                               infoUnpacker.get(), infoPrediffer.get(), nID, cmdInfo.m_nLineIndex);
+                               infoUnpacker.get(), infoPrediffer.get(), nID, &openParams);
                }
                else if (cmdInfo.m_Files.GetSize() > 1)
                {
                        DWORD dwFlags[3] = {cmdInfo.m_dwLeftFlags, cmdInfo.m_dwRightFlags, FFILEOPEN_NONE};
                        bCompared = pMainFrame->DoFileOpen(&cmdInfo.m_Files,
                                dwFlags, strDesc, cmdInfo.m_sReportFile, cmdInfo.m_bRecurse, nullptr,
-                               infoUnpacker.get(), infoPrediffer.get(), nID, cmdInfo.m_nLineIndex);
+                               infoUnpacker.get(), infoPrediffer.get(), nID, &openParams);
                }
                else if (cmdInfo.m_Files.GetSize() == 1)
                {
@@ -736,7 +745,7 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF
                        {
                                strDesc[0] = cmdInfo.m_sLeftDesc;
                                strDesc[1] = cmdInfo.m_sRightDesc;
-                               bCompared = pMainFrame->DoSelfCompare(nID, sFilepath, strDesc, nullptr, cmdInfo.m_nLineIndex);
+                               bCompared = pMainFrame->DoSelfCompare(nID, sFilepath, strDesc, nullptr, &openParams);
                        }
                        else if (IsProjectFile(sFilepath))
                        {
@@ -755,7 +764,7 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF
                                DWORD dwFlags[3] = {cmdInfo.m_dwLeftFlags, cmdInfo.m_dwRightFlags, FFILEOPEN_NONE};
                                bCompared = pMainFrame->DoFileOpen(&cmdInfo.m_Files,
                                        dwFlags, strDesc, cmdInfo.m_sReportFile, cmdInfo.m_bRecurse, nullptr,
-                                       infoUnpacker.get(), infoPrediffer.get(), nID, cmdInfo.m_nLineIndex);
+                                       infoUnpacker.get(), infoPrediffer.get(), nID, &openParams);
                        }
                }
                else if (cmdInfo.m_Files.GetSize() == 0) // if there are no input args, we can check the display file dialog flag
index 7f6ac01..da76fe1 100644 (file)
@@ -113,22 +113,22 @@ const TCHAR *MergeCmdLineInfo::SetConfig(const TCHAR *q)
  * @brief MergeCmdLineParser's constructor.
  * @param [in] q Points to the beginning of the command line.
  */
-MergeCmdLineInfo::MergeCmdLineInfo(const TCHAR *q):
-       m_nCmdShow(SHOWNORMAL),
-       m_nWindowType(AUTOMATIC),
-       m_bEscShutdown(false),
-       m_bExitIfNoDiff(Disabled),
-       m_bRecurse(false),
-       m_bNonInteractive(false),
-       m_nSingleInstance(),
-       m_bShowUsage(false),
-       m_bNoPrefs(false),
-       m_nCodepage(0),
-       m_bSelfCompare(false),
-       m_dwLeftFlags(FFILEOPEN_NONE),
-       m_dwMiddleFlags(FFILEOPEN_NONE),
-       m_dwRightFlags(FFILEOPEN_NONE),
-       m_nLineIndex(-1)
+MergeCmdLineInfo::MergeCmdLineInfo(const TCHAR* q)
+       : m_nCmdShow(SHOWNORMAL)
+       , m_nWindowType(AUTOMATIC)
+       , m_bEscShutdown(false)
+       , m_bExitIfNoDiff(Disabled)
+       , m_bRecurse(false)
+       , m_bNonInteractive(false)
+       , m_nSingleInstance()
+       , m_bShowUsage(false)
+       , m_bNoPrefs(false)
+       , m_nCodepage(0)
+       , m_bSelfCompare(false)
+       , m_dwLeftFlags(FFILEOPEN_NONE)
+       , m_dwMiddleFlags(FFILEOPEN_NONE)
+       , m_dwRightFlags(FFILEOPEN_NONE)
+       m_nLineIndex(-1)
 {
        String exeName;
        q = EatParam(q, exeName);
@@ -400,6 +400,31 @@ void MergeCmdLineInfo::ParseWinMergeCmdLine(const TCHAR *q)
                                m_nLineIndex--;
                        }
                }
+               else if (param == _T("table-delimiter"))
+               {
+                       String value;
+                       q = EatParam(q, value);
+                       value = strutils::makelower(value);
+                       if (value == _T("\\t") || value == _T("tab"))
+                               m_cTableDelimiter = '\t';
+                       else if (value == _T("\\v") || value == _T("vtab"))
+                               m_cTableDelimiter = '\v';
+                       else
+                               m_cTableDelimiter = value.c_str()[0];
+               }
+               else if (param == _T("table-quote"))
+               {
+                       String value;
+                       q = EatParam(q, value);
+                       m_cTableQuote = value.c_str()[0];
+               }
+               else if (param == _T("table-allownewlinesinquotes"))
+               {
+                       String value;
+                       q = EatParam(q, value);
+                       TCHAR c = strutils::makelower(value).c_str()[0];
+                       m_bTableAllowNewlinesInQuotes = (c == 0 || c == 'y' || c == 't' || c == '1');
+               }
                else if (param == _T("al"))
                {
                        // -al to auto-merge at the left pane
index 836a9e7..56afc44 100644 (file)
@@ -75,6 +75,9 @@ public:
        bool m_bNoPrefs; /**< Do not load or remember options (preferences) */   
        bool m_bSelfCompare; /**< Compares the specified file with a copy of the file */
        int m_nLineIndex; /**< Line number to jump after loading files */
+       std::optional<TCHAR> m_cTableDelimiter; /**< Delimiter character for table editing*/
+       std::optional<TCHAR> m_cTableQuote; /* Quote character for table editing *< */
+       std::optional<bool> m_bTableAllowNewlinesInQuotes; /**< Allow newlines in quotes */
 
        unsigned m_dwLeftFlags; /**< Left side file's behavior options. */
        unsigned m_dwMiddleFlags; /**< Middle side file's behavior options. */
index a0bfb4c..542dcbc 100644 (file)
@@ -2781,58 +2781,72 @@ DWORD CMergeDoc::LoadOneFile(int index, String filename, bool readOnly, const St
        return loadSuccess;
 }
 
-void CMergeDoc::SetTableProperties()
+CMergeDoc::TableProps CMergeDoc::GetTablePropertiesByFileName(const String& path, const std::optional<bool>& enableTableEditing, bool showDialog)
 {
-       struct TableProps { bool istable; TCHAR delimiter; TCHAR quote; bool allowNewlinesInQuotes; };
-       auto getTablePropsByFileName = [](const String& path, const std::optional<bool>& enableTableEditing)-> TableProps
+       const TCHAR quote = GetOptionsMgr()->GetString(OPT_CMP_TBL_QUOTE_CHAR).c_str()[0];
+       FileFilterHelper filterCSV, filterTSV, filterDSV;
+       bool allowNewlineIQuotes = GetOptionsMgr()->GetBool(OPT_CMP_TBL_ALLOW_NEWLINES_IN_QUOTES);
+       const String csvFilePattern = GetOptionsMgr()->GetString(OPT_CMP_CSV_FILEPATTERNS);
+       if (!csvFilePattern.empty())
        {
-               const TCHAR quote = GetOptionsMgr()->GetString(OPT_CMP_TBL_QUOTE_CHAR).c_str()[0];
-               FileFilterHelper filterCSV, filterTSV, filterDSV;
-               bool allowNewlineIQuotes = GetOptionsMgr()->GetBool(OPT_CMP_TBL_ALLOW_NEWLINES_IN_QUOTES);
-               const String csvFilePattern = GetOptionsMgr()->GetString(OPT_CMP_CSV_FILEPATTERNS);
-               if (!csvFilePattern.empty())
-               {
-                       filterCSV.UseMask(true);
-                       filterCSV.SetMask(csvFilePattern);
-                       if (filterCSV.includeFile(path))
-                               return { true, ',', quote, allowNewlineIQuotes };
-               }
-               const String tsvFilePattern = GetOptionsMgr()->GetString(OPT_CMP_TSV_FILEPATTERNS);
-               if (!tsvFilePattern.empty())
-               {
-                       filterTSV.UseMask(true);
-                       filterTSV.SetMask(tsvFilePattern);
-                       if (filterTSV.includeFile(path))
-                               return { true, '\t', quote, allowNewlineIQuotes };
-               }
-               const String dsvFilePattern = GetOptionsMgr()->GetString(OPT_CMP_DSV_FILEPATTERNS);
-               if (!dsvFilePattern.empty())
-               {
-                       filterDSV.UseMask(true);
-                       filterDSV.SetMask(dsvFilePattern);
-                       if (filterDSV.includeFile(path))
-                               return { true, GetOptionsMgr()->GetString(OPT_CMP_DSV_DELIM_CHAR).c_str()[0], quote };
-               }
-               if (enableTableEditing.value_or(false))
+               filterCSV.UseMask(true);
+               filterCSV.SetMask(csvFilePattern);
+               if (filterCSV.includeFile(path))
+                       return { true, ',', quote, allowNewlineIQuotes };
+       }
+       const String tsvFilePattern = GetOptionsMgr()->GetString(OPT_CMP_TSV_FILEPATTERNS);
+       if (!tsvFilePattern.empty())
+       {
+               filterTSV.UseMask(true);
+               filterTSV.SetMask(tsvFilePattern);
+               if (filterTSV.includeFile(path))
+                       return { true, '\t', quote, allowNewlineIQuotes };
+       }
+       const String dsvFilePattern = GetOptionsMgr()->GetString(OPT_CMP_DSV_FILEPATTERNS);
+       if (!dsvFilePattern.empty())
+       {
+               filterDSV.UseMask(true);
+               filterDSV.SetMask(dsvFilePattern);
+               if (filterDSV.includeFile(path))
+                       return { true, GetOptionsMgr()->GetString(OPT_CMP_DSV_DELIM_CHAR).c_str()[0], quote };
+       }
+       if (enableTableEditing.value_or(false))
+       {
+               if (showDialog)
                {
                        COpenTableDlg dlg;
                        if (dlg.DoModal() == IDOK)
                                return { true, dlg.m_sDelimiterChar.c_str()[0], dlg.m_sQuoteChar.c_str()[0], dlg.m_bAllowNewlinesInQuotes };
                }
-               return { false, 0, 0, false };
-       };
+               else
+               {
+                       return { true, GetOptionsMgr()->GetString(OPT_CMP_DSV_DELIM_CHAR).c_str()[0], quote };
+               }
+       }
+       return { false, 0, 0, false };
+};
 
-       TableProps tableProps[3] = {};
+void CMergeDoc::SetTableProperties()
+{
+       TableProps tableProps[3] = { };
        int nTableFileIndex = -1;
-       for (int nBuffer = 0; nBuffer < m_nBuffers; nBuffer++)
+       if (m_pTablePropsCommandLine)
        {
-               if (nBuffer == 0 ||
-                       paths::FindExtension(m_ptBuf[nBuffer - 1]->GetTempFileName()) != paths::FindExtension(m_ptBuf[nBuffer]->GetTempFileName()))
-                       tableProps[nBuffer] = getTablePropsByFileName(m_ptBuf[nBuffer]->GetTempFileName(), m_bEnableTableEditing);
-               else
-                       tableProps[nBuffer] = tableProps[nBuffer - 1];
-               if (tableProps[nBuffer].istable)
-                       nTableFileIndex = nBuffer;
+               nTableFileIndex = 0;
+               tableProps[0] = *m_pTablePropsCommandLine;
+       }
+       else
+       {
+               for (int nBuffer = 0; nBuffer < m_nBuffers; nBuffer++)
+               {
+                       if (nBuffer == 0 ||
+                               paths::FindExtension(m_ptBuf[nBuffer - 1]->GetTempFileName()) != paths::FindExtension(m_ptBuf[nBuffer]->GetTempFileName()))
+                               tableProps[nBuffer] = GetTablePropertiesByFileName(m_ptBuf[nBuffer]->GetTempFileName(), m_bEnableTableEditing);
+                       else
+                               tableProps[nBuffer] = tableProps[nBuffer - 1];
+                       if (tableProps[nBuffer].istable)
+                               nTableFileIndex = nBuffer;
+               }
        }
        for (int nBuffer = 0; nBuffer < m_nBuffers; nBuffer++)
        {
index 09cb76a..8974b15 100644 (file)
@@ -128,6 +128,7 @@ class CLocationView;
 class CMergeDoc : public CDocument, public IMergeDoc
 {
 public:
+       struct TableProps { bool istable; TCHAR delimiter; TCHAR quote; bool allowNewlinesInQuotes; };
 // Attributes
 public:
        static int m_nBuffersTemp;
@@ -314,8 +315,10 @@ public:
                                return true;
                return false;
        }
+       static TableProps GetTablePropertiesByFileName(const String& path, const std::optional<bool>& enableTableEditing, bool showDialog = true);
        std::optional<bool> GetEnableTableEditing() const { return m_bEnableTableEditing; }
        void SetEnableTableEditing(std::optional<bool> bEnableTableEditing) { m_bEnableTableEditing = bEnableTableEditing; }
+       void SetTableProperties(const TableProps& props) { m_pTablePropsCommandLine.reset(new TableProps(props)); }
        bool GetAutomaticRescan() const { return m_bAutomaticRescan; }
        // to customize the mergeview menu
        HMENU createPrediffersSubmenu(HMENU hMenu);
@@ -352,6 +355,7 @@ protected:
        bool m_bHasSyncPoints;
        bool m_bAutoMerged;
        std::optional<bool> m_bEnableTableEditing;
+       std::unique_ptr<TableProps> m_pTablePropsCommandLine;
        /**
         * Are automatic rescans enabled?
         * If automatic rescans are enabled then we rescan files after edit