annotate kdiff3/diff_ext_for_kdiff3/diff_ext.cpp @ 113:7bca1f1340f6 tip

Build fixes for Xcode 10 / Qt 5.12
author Chris Cannam
date Mon, 17 Dec 2018 11:13:01 +0000
parents fcd146072e0c
children
rev   line source
joachim99@75 1 /*
joachim99@75 2 * Copyright (c) 2003-2006, Sergey Zorin. All rights reserved.
joachim99@75 3 *
joachim99@75 4 * This software is distributable under the BSD license. See the terms
joachim99@75 5 * of the BSD license in the LICENSE file provided with this software.
joachim99@75 6 *
joachim99@75 7 */
joachim99@75 8 #define _CRT_SECURE_NO_DEPRECATE
joachim99@75 9
joachim99@75 10 #include <assert.h>
joachim99@75 11 #include <stdio.h>
joachim99@75 12 #include <tchar.h>
joachim99@75 13
joachim99@75 14 #include "diff_ext.h"
joachim99@75 15 #include <map>
joachim99@75 16 #include <vector>
joachim99@75 17
joachim99@75 18
joachim99@75 19 #ifdef UNICODE
joachim99@75 20
joachim99@75 21 static void parseString( const std::wstring& s, size_t& i /*pos*/, std::wstring& r /*result*/ )
joachim99@75 22 {
joachim99@75 23 size_t size = s.size();
joachim99@75 24 ++i; // Skip initial '"'
joachim99@75 25 for( ; i<size; ++i )
joachim99@75 26 {
joachim99@75 27 if ( s[i]=='"' )
joachim99@75 28 {
joachim99@75 29 ++i;
joachim99@75 30 break;
joachim99@75 31 }
joachim99@75 32 else if ( s[i]==L'\\' && i+1<size )
joachim99@75 33 {
joachim99@75 34 ++i;
joachim99@75 35 switch( s[i] ) {
joachim99@75 36 case L'n': r+=L'\n'; break;
joachim99@75 37 case L'r': r+=L'\r'; break;
joachim99@75 38 case L'\\': r+=L'\\'; break;
joachim99@75 39 case L'"': r+=L'"'; break;
joachim99@75 40 case L't': r+=L'\t'; break;
joachim99@75 41 default: r+=L'\\'; r+=s[i]; break;
joachim99@75 42 }
joachim99@75 43 }
joachim99@75 44 else
joachim99@75 45 r+=s[i];
joachim99@75 46 }
joachim99@75 47 }
joachim99@75 48
joachim99@75 49 static std::map< std::wstring, std::wstring > s_translationMap;
joachim99@75 50 static tstring s_translationFileName;
joachim99@75 51
joachim99@75 52 void readTranslationFile()
joachim99@75 53 {
joachim99@75 54 s_translationMap.clear();
joachim99@75 55 FILE* pFile = _tfopen( s_translationFileName.c_str(), TEXT("rb") );
joachim99@75 56 if ( pFile )
joachim99@75 57 {
joachim99@75 58 MESSAGELOG( TEXT( "Reading translations: " ) + s_translationFileName );
joachim99@75 59 std::vector<char> buffer;
joachim99@75 60 try {
joachim99@75 61 if ( fseek(pFile, 0, SEEK_END)==0 )
joachim99@75 62 {
joachim99@75 63 size_t length = ftell(pFile); // Get the file length
joachim99@75 64 buffer.resize(length);
joachim99@75 65 fseek(pFile, 0, SEEK_SET );
joachim99@75 66 fread(&buffer[0], 1, length, pFile );
joachim99@75 67 }
joachim99@75 68 }
joachim99@75 69 catch(...)
joachim99@75 70 {
joachim99@75 71 }
joachim99@75 72 fclose(pFile);
joachim99@75 73
joachim99@75 74 if (buffer.size()>0)
joachim99@75 75 {
joachim99@75 76 size_t bufferSize = buffer.size();
joachim99@75 77 int offset = 0;
joachim99@75 78 if ( buffer[0]=='\xEF' && buffer[1]=='\xBB' && buffer[2]=='\xBF' )
joachim99@75 79 {
joachim99@75 80 offset += 3;
joachim99@75 81 bufferSize -= 3;
joachim99@75 82 }
joachim99@75 83
joachim99@75 84 size_t sLength = MultiByteToWideChar(CP_UTF8,0,&buffer[offset], (int)bufferSize, 0, 0 );
joachim99@75 85 std::wstring s( sLength, L' ' );
joachim99@75 86 MultiByteToWideChar(CP_UTF8,0,&buffer[offset], (int)bufferSize, &s[0], (int)s.size() );
joachim99@75 87
joachim99@75 88 // Now analyse the file and extract translation strings
joachim99@75 89 std::wstring msgid;
joachim99@75 90 std::wstring msgstr;
joachim99@75 91 msgid.reserve( 1000 );
joachim99@75 92 msgstr.reserve( 1000 );
joachim99@75 93 bool bExpectingId = true;
joachim99@75 94 for( size_t i=0; i<sLength; ++i )
joachim99@75 95 {
joachim99@75 96 wchar_t c = s[i];
joachim99@75 97 if( c == L'\n' || c == L'\r' || c==L' ' || c==L'\t' )
joachim99@75 98 continue;
joachim99@75 99 else if ( s[i]==L'#' ) // Comment
joachim99@75 100 while( s[i]!='\n' && s[i]!=L'\r' && i<sLength )
joachim99@75 101 ++i;
joachim99@75 102 else if ( s[i]==L'"' )
joachim99@75 103 {
joachim99@75 104 if ( bExpectingId ) parseString(s,i,msgid);
joachim99@75 105 else parseString(s,i,msgstr);
joachim99@75 106 }
joachim99@75 107 else if ( sLength-i>5 && wcsncmp( &s[i], L"msgid", 5 )==0 )
joachim99@75 108 {
joachim99@75 109 if ( !msgid.empty() && !msgstr.empty() )
joachim99@75 110 {
joachim99@75 111 s_translationMap[msgid] = msgstr;
joachim99@75 112 }
joachim99@75 113 bExpectingId = true;
joachim99@75 114 msgid.clear();
joachim99@75 115 i+=4;
joachim99@75 116 }
joachim99@75 117 else if ( sLength-i>6 && wcsncmp( &s[i], L"msgstr", 6 )==0 )
joachim99@75 118 {
joachim99@75 119 bExpectingId = false;
joachim99@75 120 msgstr.clear();
joachim99@75 121 i+=5;
joachim99@75 122 }
joachim99@75 123 else
joachim99@75 124 {
joachim99@75 125 // Unexpected ?
joachim99@75 126 }
joachim99@75 127 }
joachim99@75 128 }
joachim99@75 129 }
joachim99@75 130 else
joachim99@75 131 {
joachim99@75 132 ERRORLOG( TEXT( "Reading translations failed: " ) + s_translationFileName );
joachim99@75 133 }
joachim99@75 134 }
joachim99@75 135
joachim99@75 136 static tstring getTranslation( const tstring& fallback )
joachim99@75 137 {
joachim99@75 138 std::map< std::wstring, std::wstring >::iterator i = s_translationMap.find( fallback );
joachim99@75 139 if (i!=s_translationMap.end())
joachim99@75 140 return i->second;
joachim99@75 141 return fallback;
joachim99@75 142 }
joachim99@75 143 #else
joachim99@75 144
joachim99@75 145 static tstring getTranslation( const tstring& fallback )
joachim99@75 146 {
joachim99@75 147 return fallback;
joachim99@75 148 }
joachim99@75 149
joachim99@75 150 #endif
joachim99@75 151
joachim99@75 152
joachim99@75 153 static void replaceArgs( tstring& s, const tstring& r1, const tstring& r2=TEXT(""), const tstring& r3=TEXT("") )
joachim99@75 154 {
joachim99@75 155 tstring arg1 = TEXT("%1");
joachim99@75 156 size_t pos1 = s.find( arg1 );
joachim99@75 157 tstring arg2 = TEXT("%2");
joachim99@75 158 size_t pos2 = s.find( arg2 );
joachim99@75 159 tstring arg3 = TEXT("%3");
joachim99@75 160 size_t pos3 = s.find( arg3 );
joachim99@75 161 if ( pos1 != size_t(-1) )
joachim99@75 162 {
joachim99@75 163 s.replace( pos1, arg1.length(), r1 );
joachim99@75 164 if ( pos2 != size_t(-1) && pos1<pos2 )
joachim99@75 165 pos2 += r1.length() - arg1.length();
joachim99@75 166 if ( pos3 != size_t(-1) && pos1<pos3 )
joachim99@75 167 pos3 += r1.length() - arg1.length();
joachim99@75 168 }
joachim99@75 169 if ( pos2 != size_t(-1) )
joachim99@75 170 {
joachim99@75 171 s.replace( pos2, arg2.length(), r2 );
joachim99@75 172 if ( pos3 != size_t(-1) && pos2<pos3 )
joachim99@75 173 pos3 += r2.length() - arg2.length();
joachim99@75 174 }
joachim99@75 175 if ( pos3 != size_t(-1) )
joachim99@75 176 {
joachim99@75 177 s.replace( pos3, arg3.length(), r3 );
joachim99@75 178 }
joachim99@75 179 }
joachim99@75 180
joachim99@75 181 DIFF_EXT::DIFF_EXT()
joachim99@75 182 : m_nrOfSelectedFiles(0), _ref_count(0L),
joachim99@75 183 m_recentFiles( SERVER::instance()->recent_files() )
joachim99@75 184 {
joachim99@75 185 LOG();
joachim99@75 186 _resource = SERVER::instance()->handle();
joachim99@75 187
joachim99@75 188 SERVER::instance()->lock();
joachim99@75 189 }
joachim99@75 190
joachim99@75 191 DIFF_EXT::~DIFF_EXT()
joachim99@75 192 {
joachim99@75 193 LOG();
joachim99@77 194 if(_resource != SERVER::instance()->handle()) {
joachim99@77 195 FreeLibrary(_resource);
joachim99@77 196 }
joachim99@75 197
joachim99@77 198 SERVER::instance()->release();
joachim99@75 199 }
joachim99@75 200
joachim99@75 201 STDMETHODIMP
joachim99@75 202 DIFF_EXT::QueryInterface(REFIID refiid, void** ppv)
joachim99@75 203 {
joachim99@75 204 HRESULT ret = E_NOINTERFACE;
joachim99@75 205 *ppv = 0;
joachim99@75 206
joachim99@75 207 if(IsEqualIID(refiid, IID_IShellExtInit) || IsEqualIID(refiid, IID_IUnknown)) {
joachim99@75 208 *ppv = static_cast<IShellExtInit*>(this);
joachim99@75 209 } else if (IsEqualIID(refiid, IID_IContextMenu)) {
joachim99@75 210 *ppv = static_cast<IContextMenu*>(this);
joachim99@75 211 }
joachim99@75 212
joachim99@75 213 if(*ppv != 0) {
joachim99@75 214 AddRef();
joachim99@75 215
joachim99@75 216 ret = NOERROR;
joachim99@75 217 }
joachim99@75 218
joachim99@75 219 return ret;
joachim99@75 220 }
joachim99@75 221
joachim99@75 222 STDMETHODIMP_(ULONG)
joachim99@75 223 DIFF_EXT::AddRef()
joachim99@75 224 {
joachim99@75 225 return InterlockedIncrement((LPLONG)&_ref_count);
joachim99@75 226 }
joachim99@75 227
joachim99@75 228 STDMETHODIMP_(ULONG)
joachim99@75 229 DIFF_EXT::Release()
joachim99@75 230 {
joachim99@75 231 ULONG ret = 0L;
joachim99@75 232
joachim99@75 233 if(InterlockedDecrement((LPLONG)&_ref_count) != 0) {
joachim99@75 234 ret = _ref_count;
joachim99@75 235 } else {
joachim99@75 236 delete this;
joachim99@75 237 }
joachim99@75 238
joachim99@75 239 return ret;
joachim99@75 240 }
joachim99@75 241
joachim99@75 242
joachim99@75 243
joachim99@75 244 STDMETHODIMP
joachim99@75 245 DIFF_EXT::Initialize(LPCITEMIDLIST /*folder not used*/, IDataObject* data, HKEY /*key not used*/)
joachim99@75 246 {
joachim99@75 247 LOG();
joachim99@75 248
joachim99@75 249 #ifdef UNICODE
joachim99@75 250 tstring installDir = SERVER::instance()->getRegistryKeyString( TEXT(""), TEXT("InstallDir") );
joachim99@75 251 tstring language = SERVER::instance()->getRegistryKeyString( TEXT(""), TEXT("Language") );
joachim99@75 252 tstring translationFileName = installDir + TEXT("\\translations\\diff_ext_") + language + TEXT(".po");
joachim99@75 253 if ( s_translationFileName != translationFileName )
joachim99@75 254 {
joachim99@75 255 s_translationFileName = translationFileName;
joachim99@75 256 readTranslationFile();
joachim99@75 257 }
joachim99@75 258 #endif
joachim99@75 259
joachim99@75 260 FORMATETC format = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
joachim99@75 261 STGMEDIUM medium;
joachim99@75 262 medium.tymed = TYMED_HGLOBAL;
joachim99@75 263 HRESULT ret = E_INVALIDARG;
joachim99@75 264
joachim99@75 265 if(data->GetData(&format, &medium) == S_OK)
joachim99@75 266 {
joachim99@75 267 HDROP drop = (HDROP)medium.hGlobal;
joachim99@75 268 m_nrOfSelectedFiles = DragQueryFile(drop, 0xFFFFFFFF, 0, 0);
joachim99@75 269
joachim99@75 270 TCHAR tmp[MAX_PATH];
joachim99@75 271
joachim99@75 272 //initialize_language();
joachim99@75 273
joachim99@75 274 if (m_nrOfSelectedFiles >= 1 && m_nrOfSelectedFiles <= 3)
joachim99@75 275 {
joachim99@75 276 DragQueryFile(drop, 0, tmp, MAX_PATH);
joachim99@75 277 _file_name1 = tmp;
joachim99@75 278
joachim99@75 279 if(m_nrOfSelectedFiles >= 2)
joachim99@75 280 {
joachim99@75 281 DragQueryFile(drop, 1, tmp, MAX_PATH);
joachim99@75 282 _file_name2 = tmp;
joachim99@75 283 }
joachim99@75 284
joachim99@75 285 if( m_nrOfSelectedFiles == 3)
joachim99@75 286 {
joachim99@75 287 DragQueryFile(drop, 2, tmp, MAX_PATH);
joachim99@75 288 _file_name3 = tmp;
joachim99@75 289 }
joachim99@75 290
joachim99@75 291 ret = S_OK;
joachim99@75 292 }
joachim99@75 293 }
joachim99@75 294 else
joachim99@75 295 {
joachim99@75 296 SYSERRORLOG(TEXT("GetData"));
joachim99@75 297 }
joachim99@75 298
joachim99@75 299 return ret;
joachim99@75 300 }
joachim99@75 301
joachim99@75 302 static int insertMenuItemHelper( HMENU menu, UINT id, UINT position, const tstring& text,
joachim99@75 303 UINT fState = MFS_ENABLED, HMENU hSubMenu=0 )
joachim99@75 304 {
joachim99@75 305 MENUITEMINFO item_info;
joachim99@75 306 ZeroMemory(&item_info, sizeof(item_info));
joachim99@75 307 item_info.cbSize = sizeof(MENUITEMINFO);
joachim99@75 308 item_info.wID = id;
joachim99@75 309 if (text.empty())
joachim99@75 310 { // Separator
joachim99@75 311 item_info.fMask = MIIM_TYPE;
joachim99@75 312 item_info.fType = MFT_SEPARATOR;
joachim99@75 313 item_info.dwTypeData = 0;
joachim99@75 314 }
joachim99@75 315 else
joachim99@75 316 {
joachim99@75 317 item_info.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | (hSubMenu!=0 ? MIIM_SUBMENU : 0);
joachim99@75 318 item_info.fType = MFT_STRING;
joachim99@75 319 item_info.fState = fState;
joachim99@75 320 item_info.dwTypeData = (LPTSTR)text.c_str();
joachim99@75 321 item_info.hSubMenu = hSubMenu;
joachim99@75 322 }
joachim99@75 323 if ( 0 == InsertMenuItem(menu, position, TRUE, &item_info) )
joachim99@75 324 SYSERRORLOG(TEXT("InsertMenuItem"));
joachim99@75 325 return id;
joachim99@75 326 }
joachim99@75 327
joachim99@75 328
joachim99@75 329 STDMETHODIMP
joachim99@75 330 DIFF_EXT::QueryContextMenu(HMENU menu, UINT position, UINT first_cmd, UINT /*last_cmd not used*/, UINT flags)
joachim99@75 331 {
joachim99@75 332 LOG();
joachim99@75 333 m_id_Diff = UINT(-1);
joachim99@75 334 m_id_DiffWith = UINT(-1);
joachim99@75 335 m_id_DiffLater = UINT(-1);
joachim99@75 336 m_id_MergeWith = UINT(-1);
joachim99@75 337 m_id_Merge3 = UINT(-1);
joachim99@75 338 m_id_Diff3 = UINT(-1);
joachim99@75 339 m_id_DiffWith_Base = UINT(-1);
joachim99@77 340 m_id_ClearList = UINT(-1);
joachim99@75 341 m_id_About = UINT(-1);
joachim99@75 342
joachim99@75 343 HRESULT ret = MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
joachim99@75 344
joachim99@75 345 if(!(flags & CMF_DEFAULTONLY))
joachim99@75 346 {
joachim99@75 347 /* Menu structure:
joachim99@75 348 KDiff3 -> (1 File selected): Save 'selection' for later comparison (push onto history stack)
joachim99@75 349 Compare 'selection' with first file on history stack.
joachim99@75 350 Compare 'selection' with -> choice from history stack
joachim99@75 351 Merge 'selection' with first file on history stack.
joachim99@75 352 Merge 'selection' with last two files on history stack.
joachim99@75 353 (2 Files selected): Compare 's1' with 's2'
joachim99@75 354 Merge 's1' with 's2'
joachim99@75 355 (3 Files selected): Compare 's1', 's2' and 's3'
joachim99@75 356 */
joachim99@75 357 HMENU subMenu = CreateMenu();
joachim99@75 358
joachim99@75 359 UINT id = first_cmd;
joachim99@75 360 m_id_FirstCmd = first_cmd;
joachim99@75 361
joachim99@75 362 insertMenuItemHelper( menu, id++, position++, TEXT("") ); // begin separator
joachim99@75 363
joachim99@75 364 tstring menuString;
joachim99@75 365 UINT pos2=0;
joachim99@75 366 if(m_nrOfSelectedFiles == 1)
joachim99@75 367 {
joachim99@75 368 size_t nrOfRecentFiles = m_recentFiles.size();
joachim99@77 369 tstring menuStringCompare = i18n("Compare with %1");
joachim99@77 370 tstring menuStringMerge = i18n("Merge with %1");
joachim99@77 371 tstring firstFileName;
joachim99@75 372 if( nrOfRecentFiles>=1 )
joachim99@75 373 {
joachim99@80 374 firstFileName = TEXT("'") + cut_to_length( m_recentFiles.front() ) + TEXT("'");
joachim99@75 375 }
joachim99@77 376 replaceArgs( menuStringCompare, firstFileName );
joachim99@77 377 replaceArgs( menuStringMerge, firstFileName );
joachim99@75 378 m_id_DiffWith = insertMenuItemHelper( subMenu, id++, pos2++, menuStringCompare, nrOfRecentFiles >=1 ? MFS_ENABLED : MFS_DISABLED );
joachim99@75 379 m_id_MergeWith = insertMenuItemHelper( subMenu, id++, pos2++, menuStringMerge, nrOfRecentFiles >=1 ? MFS_ENABLED : MFS_DISABLED );
joachim99@75 380
joachim99@75 381 //if( nrOfRecentFiles>=2 )
joachim99@75 382 //{
joachim99@75 383 // tstring firstFileName = cut_to_length( m_recentFiles.front() );
joachim99@75 384 // tstring secondFileName = cut_to_length( *(++m_recentFiles.begin()) );
joachim99@75 385 //}
joachim99@75 386 m_id_Merge3 = insertMenuItemHelper( subMenu, id++, pos2++, i18n("3-way merge with base"),
joachim99@75 387 nrOfRecentFiles >=2 ? MFS_ENABLED : MFS_DISABLED );
joachim99@75 388
joachim99@77 389 menuString = i18n("Save '%1' for later");
joachim99@75 390 replaceArgs( menuString, _file_name1 );
joachim99@75 391 m_id_DiffLater = insertMenuItemHelper( subMenu, id++, pos2++, menuString );
joachim99@75 392
joachim99@75 393 HMENU file_list = CreateMenu();
joachim99@75 394 std::list<tstring>::iterator i;
joachim99@75 395 m_id_DiffWith_Base = id;
joachim99@75 396 int n = 0;
joachim99@75 397 for( i = m_recentFiles.begin(); i!=m_recentFiles.end(); ++i )
joachim99@75 398 {
joachim99@75 399 tstring s = cut_to_length( *i );
joachim99@75 400 insertMenuItemHelper( file_list, id++, n, s );
joachim99@75 401 ++n;
joachim99@75 402 }
joachim99@75 403
joachim99@77 404 insertMenuItemHelper( subMenu, id++, pos2++, i18n("Compare with ..."),
joachim99@75 405 nrOfRecentFiles > 0 ? MFS_ENABLED : MFS_DISABLED, file_list );
joachim99@77 406
joachim99@77 407 m_id_ClearList = insertMenuItemHelper( subMenu, id++, pos2++, i18n("Clear list"), nrOfRecentFiles >=1 ? MFS_ENABLED : MFS_DISABLED );
joachim99@75 408 }
joachim99@75 409 else if(m_nrOfSelectedFiles == 2)
joachim99@75 410 {
joachim99@75 411 //= "Diff " + cut_to_length(_file_name1, 20)+" and "+cut_to_length(_file_name2, 20);
joachim99@75 412 m_id_Diff = insertMenuItemHelper( subMenu, id++, pos2++, i18n("Compare") );
joachim99@75 413 }
joachim99@75 414 else if ( m_nrOfSelectedFiles == 3 )
joachim99@75 415 {
joachim99@75 416 m_id_Diff3 = insertMenuItemHelper( subMenu, id++, pos2++, i18n("3 way comparison") );
joachim99@75 417 }
joachim99@75 418 else
joachim99@75 419 {
joachim99@75 420 // More than 3 files selected?
joachim99@75 421 }
joachim99@75 422 m_id_About = insertMenuItemHelper( subMenu, id++, pos2++, i18n("About Diff-Ext ...") );
joachim99@75 423
joachim99@75 424 insertMenuItemHelper( menu, id++, position++, TEXT("KDiff3"), MFS_ENABLED, subMenu );
joachim99@75 425
joachim99@75 426 insertMenuItemHelper( menu, id++, position++, TEXT("") ); // final separator
joachim99@75 427
joachim99@75 428 ret = MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, id-first_cmd);
joachim99@75 429 }
joachim99@75 430
joachim99@75 431 return ret;
joachim99@75 432 }
joachim99@75 433
joachim99@75 434 STDMETHODIMP
joachim99@75 435 DIFF_EXT::InvokeCommand(LPCMINVOKECOMMANDINFO ici)
joachim99@75 436 {
joachim99@75 437 HRESULT ret = NOERROR;
joachim99@75 438
joachim99@75 439 _hwnd = ici->hwnd;
joachim99@75 440
joachim99@75 441 if(HIWORD(ici->lpVerb) == 0)
joachim99@75 442 {
joachim99@75 443 UINT id = m_id_FirstCmd + LOWORD(ici->lpVerb);
joachim99@75 444 if(id == m_id_Diff)
joachim99@75 445 {
joachim99@75 446 LOG();
joachim99@75 447 diff( TEXT("\"") + _file_name1 + TEXT("\" \"") + _file_name2 + TEXT("\"") );
joachim99@75 448 }
joachim99@75 449 else if(id == m_id_Diff3)
joachim99@75 450 {
joachim99@75 451 LOG();
joachim99@75 452 diff( TEXT("\"") + _file_name1 + TEXT("\" \"") + _file_name2 + TEXT("\" \"") + _file_name3 + TEXT("\"") );
joachim99@75 453 }
joachim99@75 454 else if(id == m_id_Merge3)
joachim99@75 455 {
joachim99@75 456 LOG();
joachim99@75 457 std::list< tstring >::iterator iFrom = m_recentFiles.begin();
joachim99@75 458 std::list< tstring >::iterator iBase = iFrom;
joachim99@75 459 ++iBase;
joachim99@75 460 diff( TEXT("-m \"") + *iBase + TEXT("\" \"") + *iFrom + TEXT("\" \"") + _file_name1 + TEXT("\"") );
joachim99@75 461 }
joachim99@75 462 else if(id == m_id_DiffWith)
joachim99@75 463 {
joachim99@75 464 LOG();
joachim99@75 465 diff_with(0, false);
joachim99@75 466 }
joachim99@75 467 else if(id == m_id_MergeWith)
joachim99@75 468 {
joachim99@75 469 LOG();
joachim99@75 470 diff_with(0, true);
joachim99@75 471 }
joachim99@77 472 else if(id == m_id_ClearList)
joachim99@77 473 {
joachim99@77 474 LOG();
joachim99@77 475 m_recentFiles.clear();
joachim99@77 476 }
joachim99@75 477 else if(id == m_id_DiffLater)
joachim99@75 478 {
joachim99@75 479 MESSAGELOG(TEXT("Diff Later: ")+_file_name1);
joachim99@75 480 m_recentFiles.remove( _file_name1 );
joachim99@75 481 m_recentFiles.push_front( _file_name1 );
joachim99@75 482 }
joachim99@75 483 else if(id >= m_id_DiffWith_Base && id < m_id_DiffWith_Base+m_recentFiles.size())
joachim99@75 484 {
joachim99@75 485 LOG();
joachim99@75 486 diff_with(id-m_id_DiffWith_Base, false);
joachim99@75 487 }
joachim99@75 488 else if(id == m_id_About)
joachim99@75 489 {
joachim99@75 490 LOG();
joachim99@75 491 MessageBox( _hwnd, (i18n("Diff-Ext Copyright (c) 2003-2006, Sergey Zorin. All rights reserved.\n")
joachim99@75 492 + i18n("This software is distributable under the BSD license.\n")
joachim99@75 493 + i18n("Some extensions for KDiff3 by Joachim Eibl.\n")
joachim99@75 494 + i18n("Homepage for Diff-Ext: http://diff-ext.sourceforge.net\n")
joachim99@75 495 + i18n("Homepage for KDiff3: http://kdiff3.sourceforge.net")).c_str()
joachim99@75 496 , i18n("About Diff-Ext for KDiff3").c_str(), MB_OK );
joachim99@75 497 }
joachim99@75 498 else
joachim99@75 499 {
joachim99@75 500 ret = E_INVALIDARG;
joachim99@75 501 TCHAR verb[80];
joachim99@75 502 _sntprintf(verb, 79, TEXT("Command id: %d"), LOWORD(ici->lpVerb));
joachim99@75 503 verb[79]=0;
joachim99@75 504 ERRORLOG(verb);
joachim99@75 505 }
joachim99@75 506 }
joachim99@80 507 else
joachim99@80 508 {
joachim99@80 509 ret = E_INVALIDARG;
joachim99@80 510 }
joachim99@75 511
joachim99@75 512 return ret;
joachim99@75 513 }
joachim99@75 514
joachim99@75 515 STDMETHODIMP
joachim99@75 516 DIFF_EXT::GetCommandString(UINT idCmd, UINT uFlags, UINT*, LPSTR pszName, UINT cchMax)
joachim99@75 517 {
joachim99@75 518 // LOG(); // Gets called very often
joachim99@75 519 HRESULT ret = NOERROR;
joachim99@75 520
joachim99@75 521 if(uFlags == GCS_HELPTEXT) {
joachim99@75 522 tstring helpString;
joachim99@75 523 if( idCmd == m_id_Diff )
joachim99@75 524 {
joachim99@75 525 helpString = i18n("Compare selected files");
joachim99@75 526 }
joachim99@75 527 else if( idCmd == m_id_DiffWith )
joachim99@75 528 {
joachim99@75 529 if(!m_recentFiles.empty())
joachim99@75 530 {
joachim99@75 531 helpString = i18n("Compare '%1' with '%2'");
joachim99@75 532 replaceArgs( helpString, _file_name1, m_recentFiles.front() );
joachim99@75 533 }
joachim99@75 534 }
joachim99@75 535 else if(idCmd == m_id_DiffLater)
joachim99@75 536 {
joachim99@75 537 helpString = i18n("Save '%1' for later operation");
joachim99@75 538 replaceArgs( helpString, _file_name1 );
joachim99@75 539 }
joachim99@75 540 else if((idCmd >= m_id_DiffWith_Base) && (idCmd < m_id_DiffWith_Base+m_recentFiles.size()))
joachim99@75 541 {
joachim99@75 542 if( !m_recentFiles.empty() )
joachim99@75 543 {
joachim99@75 544 unsigned int num = idCmd - m_id_DiffWith_Base;
joachim99@75 545 std::list<tstring>::iterator i = m_recentFiles.begin();
joachim99@75 546 for(unsigned int j = 0; j < num && i != m_recentFiles.end(); j++)
joachim99@75 547 i++;
joachim99@75 548
joachim99@75 549 if ( i!=m_recentFiles.end() )
joachim99@75 550 {
joachim99@75 551 helpString = i18n("Compare '%1' with '%2'");
joachim99@75 552 replaceArgs( helpString, _file_name1, *i );
joachim99@75 553 }
joachim99@75 554 }
joachim99@75 555 }
joachim99@75 556 lstrcpyn( (LPTSTR)pszName, helpString.c_str(), cchMax );
joachim99@75 557 }
joachim99@75 558
joachim99@75 559 return ret;
joachim99@75 560 }
joachim99@75 561
joachim99@75 562 void
joachim99@75 563 DIFF_EXT::diff( const tstring& arguments )
joachim99@75 564 {
joachim99@75 565 LOG();
joachim99@75 566 STARTUPINFO si;
joachim99@75 567 PROCESS_INFORMATION pi;
joachim99@75 568 bool bError = true;
joachim99@75 569 tstring command = SERVER::instance()->getRegistryKeyString( TEXT(""), TEXT("diffcommand") );
joachim99@75 570 tstring commandLine = TEXT("\"") + command + TEXT("\" ") + arguments;
joachim99@75 571 if ( ! command.empty() )
joachim99@75 572 {
joachim99@75 573 ZeroMemory(&si, sizeof(si));
joachim99@75 574 si.cb = sizeof(si);
joachim99@75 575 if (CreateProcess(command.c_str(), (LPTSTR)commandLine.c_str(), 0, 0, FALSE, 0, 0, 0, &si, &pi) == 0)
joachim99@75 576 {
joachim99@75 577 SYSERRORLOG(TEXT("CreateProcess") + command);
joachim99@75 578 }
joachim99@75 579 else
joachim99@75 580 {
joachim99@75 581 bError = false;
joachim99@75 582 CloseHandle( pi.hProcess );
joachim99@75 583 CloseHandle( pi.hThread );
joachim99@75 584 }
joachim99@75 585 }
joachim99@75 586
joachim99@75 587 if (bError)
joachim99@75 588 {
joachim99@75 589 tstring message = i18n("Could not start KDiff3. Please rerun KDiff3 installation.");
joachim99@75 590 message += TEXT("\n") + i18n("Command") + TEXT(": ") + command;
joachim99@75 591 message += TEXT("\n") + i18n("CommandLine") + TEXT(": ") + commandLine;
joachim99@75 592 MessageBox(_hwnd, message.c_str(), i18n("Diff-Ext For KDiff3").c_str(), MB_OK);
joachim99@75 593 }
joachim99@75 594 }
joachim99@75 595
joachim99@75 596 void
joachim99@75 597 DIFF_EXT::diff_with(unsigned int num, bool bMerge)
joachim99@75 598 {
joachim99@75 599 LOG();
joachim99@75 600 std::list<tstring>::iterator i = m_recentFiles.begin();
joachim99@75 601 for(unsigned int j = 0; j < num && i!=m_recentFiles.end(); j++) {
joachim99@75 602 i++;
joachim99@75 603 }
joachim99@75 604
joachim99@75 605 if ( i!=m_recentFiles.end() )
joachim99@75 606 _file_name2 = *i;
joachim99@75 607
joachim99@77 608 diff( (bMerge ? TEXT("-m \"") : TEXT("\"") ) + _file_name2 + TEXT("\" \"") + _file_name1 + TEXT("\"") );
joachim99@75 609 }
joachim99@75 610
joachim99@75 611
joachim99@75 612 tstring
joachim99@75 613 DIFF_EXT::cut_to_length(const tstring& in, size_t max_len)
joachim99@75 614 {
joachim99@75 615 tstring ret;
joachim99@75 616 if( in.length() > max_len)
joachim99@75 617 {
joachim99@75 618 ret = in.substr(0, (max_len-3)/2);
joachim99@75 619 ret += TEXT("...");
joachim99@75 620 ret += in.substr( in.length()-(max_len-3)/2 );
joachim99@75 621 }
joachim99@75 622 else
joachim99@75 623 {
joachim99@75 624 ret = in;
joachim99@75 625 }
joachim99@75 626
joachim99@75 627 return ret;
joachim99@75 628 }