├── .github └── FUNDING.yml ├── .gitignore ├── CMakeLists.txt ├── Compare-plugin_ReleaseNotes.txt ├── Help.md ├── README.md ├── ReleaseNotes.txt ├── appveyor.yml ├── libs ├── arm64 │ └── git2.dll ├── x64 │ ├── git2.dll │ └── sqlite3.dll └── x86 │ ├── git2.dll │ └── sqlite3.dll ├── license.txt ├── projects └── 2022 │ ├── ComparePlus.sln │ └── ComparePlus.vcxproj ├── res ├── Fluent │ ├── ClearCompareFluent.ico │ ├── CompareFluent.ico │ ├── CompareLinesFluent.ico │ ├── DiffsOnlyFluent.ico │ ├── FirstFluent.ico │ ├── FirstToCompareFluent.ico │ ├── FirstToCompareRTLFluent.ico │ ├── LastFluent.ico │ ├── NavBarFluent.ico │ ├── NextFluent.ico │ └── PreviousFluent.ico ├── FluentDM │ ├── ClearCompareFluentDM.ico │ ├── CompareFluentDM.ico │ ├── CompareLinesFluentDM.ico │ ├── DiffsOnlyFluentDM.ico │ ├── FirstFluentDM.ico │ ├── FirstToCompareFluentDM.ico │ ├── FirstToCompareRTLFluentDM.ico │ ├── LastFluentDM.ico │ ├── NavBarFluentDM.ico │ ├── NextFluentDM.ico │ └── PreviousFluentDM.ico └── Standard │ ├── ClearCompare.bmp │ ├── Compare.bmp │ ├── CompareDocking.ico │ ├── CompareLines.bmp │ ├── DiffsOnly.bmp │ ├── First.bmp │ ├── FirstToCompare.bmp │ ├── FirstToCompareRTL.bmp │ ├── Last.bmp │ ├── NavBar.bmp │ ├── Next.bmp │ └── Previous.bmp └── src ├── AboutDlg ├── AboutDialog.cpp ├── AboutDialog.h ├── URLCtrl.cpp └── URLCtrl.h ├── Compare.cpp ├── Compare.h ├── Compare.rc ├── CompareOptionsDlg ├── CompareOptionsDialog.cpp └── CompareOptionsDialog.h ├── Engine ├── Engine.cpp ├── Engine.h ├── diff.h ├── fast_myers_diff.h └── varray.h ├── Icons ├── icon_added.h ├── icon_arrows.h ├── icon_changed.h ├── icon_moved.h └── icon_removed.h ├── LibGit2 ├── LibGit2Helper.cpp └── LibGit2Helper.h ├── LibHelpers.cpp ├── LibHelpers.h ├── NavDlg ├── NavDialog.cpp └── NavDialog.h ├── NppAPI ├── DockingFeature │ ├── Docking.h │ ├── DockingDlgInterface.h │ ├── StaticDialog.cpp │ ├── StaticDialog.h │ ├── Window.h │ └── dockingResource.h ├── Notepad_plus_msgs.h ├── NppInternalDefines.h ├── PluginInterface.h ├── Sci_Position.h ├── Scintilla.h └── menuCmdID.h ├── NppHelpers.cpp ├── NppHelpers.h ├── ProgressDlg ├── ProgressDlg.cpp └── ProgressDlg.h ├── SQLite ├── SqliteHelper.cpp └── SqliteHelper.h ├── SettingsDlg ├── ColorCombo.cpp ├── ColorCombo.h ├── ColorPopup.cpp ├── ColorPopup.h ├── SettingsDialog.cpp └── SettingsDialog.h ├── Tools.cpp ├── Tools.h ├── UserSettings.cpp ├── UserSettings.h ├── mingw-std-threads ├── LICENSE ├── README.md ├── mingw.condition_variable.h ├── mingw.future.h ├── mingw.mutex.h ├── mingw.shared_mutex.h ├── mingw.thread.h └── tests │ ├── CMakeLists.txt │ └── tests.cpp └── resource.h /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | custom: 'https://www.paypal.com/paypalme/pnedev' 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | #ignore thumbnails created by windows 3 | Thumbs.db 4 | #Ignore files build by Visual Studio 5 | .vs/ 6 | *.obj 7 | *.pdb 8 | *.user 9 | *.aps 10 | *.pch 11 | *.vspscc 12 | *_i.c 13 | *_p.c 14 | *.ncb 15 | *.suo 16 | *.tlb 17 | *.tlh 18 | *.bak 19 | *.vsp 20 | *.cache 21 | *.ilk 22 | *.log 23 | *.lib 24 | *.sbr 25 | *.sdf 26 | *.opendb 27 | *.opensdf 28 | [rR]elease*/ 29 | [dD]ebug*/ 30 | Notepad++/ 31 | *~ 32 | *.swp 33 | *.ipch 34 | *.exp 35 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.12) 2 | 3 | set (CMAKE_SYSTEM_NAME Windows) 4 | 5 | option (WIN64 "Win 64-bit build" ON) 6 | option (MULTITHREAD "Multithread change detection" OFF) 7 | option (OTHER_MOVED_ICONS "Use alternative moves lines icons" ON) 8 | 9 | # On Cmake invokation if debug logging is desired set the value of DLOG to include the bit-flag of each desired 10 | # function to log: 11 | # bit 0 - log compare algorithm 12 | # bit 1 - log views synchronization 13 | # bit 2 - log Notepad++ and Scintilla notifications 14 | # bit 3 - log navigation commands diff visiting 15 | set (DLOG 0 CACHE STRING "Flags for debug log messages") 16 | 17 | if (UNIX OR MINGW) 18 | set (CMAKE_SYSROOT "/usr") 19 | 20 | set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 21 | set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 22 | set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 23 | 24 | if (WIN64) 25 | set (toolchain_prefix x86_64-w64-mingw32) 26 | else () 27 | set (toolchain_prefix i686-w64-mingw32) 28 | endif () 29 | 30 | set (CMAKE_C_COMPILER ${CMAKE_SYSROOT}/bin/${toolchain_prefix}-gcc) 31 | set (CMAKE_CXX_COMPILER ${CMAKE_SYSROOT}/bin/${toolchain_prefix}-g++) 32 | set (CMAKE_RC_COMPILER ${CMAKE_SYSROOT}/bin/${toolchain_prefix}-windres) 33 | 34 | set (win32_inc_dir ${CMAKE_SYSROOT}/${toolchain_prefix}/include) 35 | set (win32_lib_dir ${CMAKE_SYSROOT}/${toolchain_prefix}/lib) 36 | endif () 37 | 38 | project (ComparePlus) 39 | 40 | if (UNIX OR MINGW) 41 | set (defs 42 | -DUNICODE -D_UNICODE -DMINGW_HAS_SECURE_API=1 -D_WIN32 -DWIN32 43 | -D_WIN32_WINNT=0x0600 -DWIN32_LEAN_AND_MEAN -DNOCOMM -DUNIX 44 | ) 45 | 46 | if (NOT DEBUG) 47 | set (defs ${defs} -DNDEBUG) 48 | endif () 49 | 50 | if (WIN64) 51 | set (defs ${defs} -DWIN64) 52 | message ("Win64 build is ON") 53 | endif () 54 | 55 | if (MULTITHREAD) 56 | set (defs ${defs} -DMULTITHREAD) 57 | message ("Multithread change detection is ON") 58 | endif () 59 | 60 | if (DLOG) 61 | set (defs ${defs} -DDLOG=${DLOG}) 62 | message ("Debug log flags value: ${DLOG}") 63 | endif () 64 | 65 | if (OTHER_MOVED_ICONS) 66 | set (defs ${defs} -DOTHER_MOVED_ICONS) 67 | message ("Using alternative moved lines icons.") 68 | endif () 69 | 70 | set (CMAKE_CXX_FLAGS 71 | "-std=c++14 -O3 -static-libgcc -static-libstdc++ -Wall -Wno-unknown-pragmas" 72 | ) 73 | 74 | set (CMAKE_MODULE_LINKER_FLAGS 75 | "-s" 76 | ) 77 | 78 | set (CMAKE_SHARED_MODULE_PREFIX "") 79 | else () 80 | set (defs 81 | -DUNICODE -D_UNICODE -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES -D_WIN32 -DWIN32 82 | -D_WIN32_WINNT=0x0600 -DWIN32_LEAN_AND_MEAN -DNOCOMM -DMULTITHREAD 83 | ) 84 | 85 | set (CMAKE_CXX_FLAGS 86 | "/EHsc /LD /MT /MP /W4" 87 | ) 88 | endif () 89 | 90 | set (project_rc_files 91 | src/Compare.rc 92 | ) 93 | 94 | set (project_sources 95 | src/NppAPI/DockingFeature/StaticDialog.cpp 96 | src/AboutDlg/URLCtrl.cpp 97 | src/AboutDlg/AboutDialog.cpp 98 | src/SettingsDlg/ColorCombo.cpp 99 | src/SettingsDlg/ColorPopup.cpp 100 | src/SettingsDlg/SettingsDialog.cpp 101 | src/CompareOptionsDlg/CompareOptionsDialog.cpp 102 | src/NavDlg/NavDialog.cpp 103 | src/ProgressDlg/ProgressDlg.cpp 104 | src/Engine/Engine.cpp 105 | src/Tools.cpp 106 | src/UserSettings.cpp 107 | src/Compare.cpp 108 | src/LibGit2/LibGit2Helper.cpp 109 | src/NppHelpers.cpp 110 | src/LibHelpers.cpp 111 | src/SQLite/SqliteHelper.cpp 112 | ) 113 | 114 | include_directories ( 115 | ${win32_inc_dir} 116 | src/ 117 | src/NppAPI/ 118 | src/NppAPI/DockingFeature/ 119 | src/Icons/ 120 | src/Engine/ 121 | src/AboutDlg/ 122 | src/SettingsDlg/ 123 | src/CompareOptionsDlg/ 124 | src/NavDlg/ 125 | src/ProgressDlg/ 126 | src/SQLite/ 127 | src/LibGit2/ 128 | ) 129 | 130 | add_definitions (${defs}) 131 | 132 | add_library (ComparePlus MODULE ${project_rc_files} ${project_sources}) 133 | 134 | if (UNIX OR MINGW) 135 | find_library (comctl32 136 | NAMES libcomctl32.a 137 | PATHS ${win32_lib_dir} 138 | ) 139 | 140 | find_library (comdlg32 141 | NAMES libcomdlg32.a 142 | PATHS ${win32_lib_dir} 143 | ) 144 | 145 | find_library (shlwapi 146 | NAMES libshlwapi.a 147 | PATHS ${win32_lib_dir} 148 | ) 149 | 150 | find_library (msimg32 151 | NAMES libmsimg32.a 152 | PATHS ${win32_lib_dir} 153 | ) 154 | 155 | find_library (uxtheme 156 | NAMES libuxtheme.a 157 | PATHS ${win32_lib_dir} 158 | ) 159 | 160 | target_link_libraries (ComparePlus ${comctl32} ${comdlg32} ${shlwapi} ${msimg32} ${uxtheme}) 161 | 162 | set (INSTALL_PATH 163 | "$ENV{HOME}/wine/drive_c/Program Files/Notepad++/plugins/ComparePlus" 164 | ) 165 | 166 | install (FILES ${CMAKE_BINARY_DIR}/ComparePlus.dll 167 | DESTINATION "${INSTALL_PATH}" 168 | ) 169 | else () 170 | target_link_libraries (ComparePlus comctl32 comdlg32 shlwapi msimg32 uxtheme) 171 | 172 | set (INSTALL_PATH 173 | "${PROJECT_SOURCE_DIR}/Notepad++/plugins/ComparePlus" 174 | ) 175 | 176 | install (TARGETS ComparePlus 177 | DESTINATION "${INSTALL_PATH}" 178 | ) 179 | endif () 180 | 181 | message ("Install destination: ${INSTALL_PATH}") 182 | 183 | if (CMAKE_SIZEOF_VOID_P EQUAL 8) 184 | if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm" OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch") 185 | install (DIRECTORY libs/arm64/ 186 | DESTINATION "${INSTALL_PATH}/libs" 187 | ) 188 | else() 189 | install (DIRECTORY libs/x64/ 190 | DESTINATION "${INSTALL_PATH}/libs" 191 | ) 192 | endif() 193 | else() 194 | install (DIRECTORY libs/x86/ 195 | DESTINATION "${INSTALL_PATH}/libs" 196 | ) 197 | endif() 198 | -------------------------------------------------------------------------------- /Compare-plugin_ReleaseNotes.txt: -------------------------------------------------------------------------------- 1 | Changelog: 2 | ---------- 3 | 4 | 2.0.0.0 5 | 6 | - Major Compare plugin re-work, big portions of the code are re-written. 7 | - Fix crashes and unstable behavior. 8 | - Fix memory leaks. 9 | - Improved compare algorithm in both accuracy and speed. 10 | - Reduced memory usage. 11 | - Support for unlimited active compares. 12 | - 'Set First' command added to select the first file to compare (that removes the need to manually 13 | move one of the files to the other view before comparing). 14 | - Better N++ notifications handling - closing or moving compared files is handled appropriately 15 | and doesn't lead to weird/unexpected results. 16 | - Proper file positions restoring after closing the compare. 17 | - Greatly improved Navigation bar. 18 | - Improved Compare progress behavior - it now accurately represents the compare process. 19 | - Improved settings dialog - the plugin behavior / results presentation is more customizable now. 20 | - Better results synchronization in case of wrap around active setting and in general. 21 | - Added compare toolbar icons (thanks to Yaron). 22 | - Better compare results line margin symbols (thanks to Yaron). 23 | - Better default diff colors (thanks to Yaron). 24 | - Updated for 64-bit build (thanks to Christian Grasser - chcg). 25 | - Added VS2015 project (thanks to Waldi Ravens - xylographe). 26 | - Numerous bug fixes and improvements. 27 | 28 | [1.5.7] 29 | [ 1. NEW: *** Compare released under GPLv3 ***] 30 | [ 2. NEW: Change behavior when files match (immediately exit compare)] 31 | [ 3. FIX: Some menu items where not disabled anymore when compare is not running] 32 | [* This version was never released by J. Leroy, but its changes are downmerged since *] 33 | [* version 1.5.6.3. Also I (ufo) will never make any version number higher than 1.5.6.x, *] 34 | [* since I don't know if 1.5.7 will ever get released. *] 35 | 36 | 1.5.6.7 37 | 38 | 1. NEW: Show progress bar dialog while comparing (thanks to Pavel N.!) 39 | NOTE: Due to the sophisticated nonlinear diff algorithm a truly estimated progress seems 40 | not doable, thus the progress sometimes gets recalculated (jumps back some steps) and 41 | sometimes finishes before reaching 100%! 42 | 2. NEW: "Blank" color gets auto calculated in respect of the current theme (removed from settings) 43 | NOTE: Requires N++ version 6.6.8 or higher! 44 | 3. NEW: Sync zoom levels of both views when comparing 45 | 4. FIX: Not comparing with temp file, when original file is not the last one the document tab bar 46 | 5. FIX: Too low "diff size limit" (e.g plug-in exception when comparing a 1.5 MB file with a 1 KB file) 47 | 6. FIX: Again some minor improvements to coloring and nav bar 48 | 49 | 1.5.6.6 50 | 51 | 1. NEW: Loader for using N++ as an external diff viewer (e.g. in TortoiseSVN, TortoiseGit, ..) 52 | Syntax: .../Notepad++/plugins/ComparePlugin/compare.exe 53 | 2. NEW: Use default background color of current theme as background color for nav bar 54 | 3. FIX: Exception after confirming options dialog when navigation bar isn't used 55 | 4. FIX: Miscellaneous minor fixes and improvements for the nav bar 56 | 57 | 1.5.6.5 58 | 59 | 1. NEW: Flash window when restarting "Previous" or "Next" diff search from top or 60 | bottom (a la N++'s "Wrap around" search mode) 61 | 2. NEW: Auto "Clear Results" when closing one of both compared files 62 | 3. NEW: Warning message box before displaying high amount of differing lines (more than 1000) 63 | 4. NEW: Navigation bar: Better visibility of small diff places in large documents (minimum height of 25 pixels) 64 | 5. FIX: Navigation bar: Wrong display in wrapped mode 65 | 6. FIX: Navigation bar: Dragged selection jumping to bottom when dragging above top 66 | 7. FIX: Navigation bar: Selection not changing after first click (only after second click) 67 | 8. FIX: Navigation bar: Scrolling by clicking (regression in 1.5.6.4) 68 | 9. FIX: Mouse scrolling in inactive view (regression in 1.5.6.4) 69 | 10. FIX: Automatically jump to first difference after comparison (regression in 1.5.6.4) 70 | 11. FIX: Don't always force focusing second view after comparing 71 | 12. FIX: Focus not returned to N++ after first comparison 72 | 73 | 1.5.6.4 74 | 75 | 1. NEW: Support viewing differences in "Word wrap" mode 76 | 2. FIX: Restore "Synchronize Vertical Scrolling" and "Synchronize Horizontal Scrolling" after "Clear Results" 77 | 78 | 1.5.6.3 79 | 80 | 1. NEW: Automatically jump to first difference after comparison 81 | 2. NEW: 'Compare against GIT base' 82 | (therefor using libgit2: http://libgit2.github.com/) 83 | 3. FIX: 'Compare against SVN base' doesn't work with newer SVN versions (1.7 and above) 84 | (therefor using SQLite: http://www.sqlite.org/) 85 | 86 | 1.5.6.2 87 | 88 | 1. FIX: Small changes not visible in navigation bar (in bigger files) (thx to Rolf P.) 89 | 2. FIX: Syntax highlighting broken after 'Compare' and 'Clear Results' (since N++ 6.2.1) 90 | 3. FIX: Change highlight not visible (since N++ 6.2.1) 91 | 92 | 1.5.6.1 93 | 94 | 1. FIX: Weird focus clipping while shutting down (no application gets focus again, when N++ is gone). 95 | 96 | 1.5.6 97 | 98 | 1. NEW: "Previous" and "Next" commands now jumping blockwise instead of linewise. 99 | 2. NEW: When comparing to last save or SVN base: Temp files now inherit the language highlighting from the original file. 100 | 3. NEW: Marker icons for moved state. 101 | 4. FIX: Restoring of "Synchronize Horizontal Scrolling" check state after "Clear results". 102 | 5. FIX: Swapping of "Navigation bar" check state when N++ starts after it was closed with opened navigation bar. 103 | 6. CHANGED: When comparing to last save or SVN base: Show temp files in first view (left side) instead of second view. 104 | 7. CHANGED: More intuitive default highlighting colors (green=new, red=deleted, yellow=changed, blue=moved). 105 | 8. CHANGED: Navigation bar background color now system's active caption color. 106 | 107 | 1.5.5 108 | 109 | 1. Side bar can now be used to scroll. 110 | 2. Fixed an issue causing N++ to crash when comparing R/O files. 111 | 112 | 1.5.4 113 | 114 | 1. New side bar showing a graphical view of comparison results. 115 | 2. New navigation keys (go to first/next/previous/last result). 116 | 3. Compare released in both UNICODE and ANSI version. 117 | 4. New markers icons. 118 | 119 | 1.5.3 120 | 121 | 1. New Option and About menu entry, thanks to Jens. 122 | 2. Colors used for comparison results are now configurable in Option menu 123 | (there is now no need to edit Compare.ini). 124 | 3. Compare to last save shortcut move to Alt+S 125 | 4. Compare against SVN base shortcut move to Alt+B 126 | 5. Bookmark and Compare marker bugs resolved, thanks to Thell 127 | 128 | 1.5.2 129 | 130 | 1.5.1 131 | 132 | 1. New colors. Thanks to Mark Baines for the suggestions 133 | 2. Fixes ( Thanks to Todd Schmitt for the excellent QA): 134 | Memory leak fixed 135 | Letters were getting cut off if the Formats weren't Windows 136 | Occasionaly the some letters were cut off at the end of the file 137 | Crash bug if there was a blank line at the beginning of the document 138 | 139 | 1.5 140 | 141 | 1. "Align Matches", "Detect Moves", and "Ignore spaces" are now options 142 | 2. "Show Changes since last save" option added in case you want to see the differences 143 | since you last saved, or if the file is modified outside of Notepad++ and 144 | you want to see those changes 145 | 3. "Compare with SVN base" if the file is in a svn repository you can see the 146 | changes since you last committed 147 | 4. There is now a colors section in the compare.ini to change the colors 148 | 5. Fixed a bug in the change detection 149 | 6. Compare checks to see if enough files are open before it checks if it has the right version. 150 | 151 | 152 | 1.4 153 | 154 | 1. Fixed Issue where plugin would hang if you cleared a result that had an extra line at the end 155 | 2. Fixed a bug where matches in the middle of insert and delete blocks would not line up properly 156 | 3. Fixed bug that would delete a empty line on clear if there was a blank line under it 157 | 4. Compares hashes of strings instead of the full string for some fairly significant speed improvements 158 | 5. Changed lines are compared at the word level instead of the letter, which provides some more accurate results 159 | 6. Spaces are no longer considered when comparing matches 160 | 161 | 162 | 1.3 163 | 164 | 1. New feature! Matches will now sync up with each other, so its easier to see the differences in the files. 165 | Much like how winmerge or some of the other major diff tools look. (thanks for the help Jens) 166 | 167 | 1.2.1 168 | 169 | 1. Bug fix: 170 | Compare would hang if only one tab is open 171 | 2. If compare moves a tab to another panel, than it will now move it back when the user selects Clear 172 | 3. Optimization: 173 | When possible, changes are shifted to make the results more readable. 174 | 175 | 1.2 176 | 177 | 1. By very, very popular demand: If two panels aren't already selected, the plugin will move the current tab 178 | into the second panel and than run the compare. 179 | 2. Improved Moved detection. 180 | 3. Vastly improved Changed detection. Only lines that were actually modified will show up as green, 181 | and the parts of the line that are different are highlighted. 182 | 4. Horizontal and vertical syncronization are enabled by default. (thanks to jenslorenz) 183 | 5. Fixed bug where files claimed to be identical if there was only one change. (Thanks to nicolasjolet) 184 | 185 | 1.1 186 | 187 | 1. Fixed bug where display would not immediately show the changes after compare. 188 | 2. Changed the way lines were marked to improve performance 189 | 3. There is now a prompt to notify you if the two files are identical 190 | 4. A description of each of the colors meaning was added to the about dialog box 191 | 5. A very crude "moved" detection algorithm was added. So lines that are the same but just 192 | in a different place are now marked as grey 193 | 194 | 195 | 196 | -------------------------------------------------------------------------------- /Help.md: -------------------------------------------------------------------------------- 1 | **Some Notepad++ Features** 2 | 3 | *Single-View mode:* 4 | ![image](https://cloud.githubusercontent.com/assets/10229320/23313224/7a845b98-fac5-11e6-8c03-51e0497c139e.png) 5 | 6 | *Double-View mode:* 7 | ![image](https://cloud.githubusercontent.com/assets/10229320/23313393/29c7a4ac-fac6-11e6-880a-10c5f783ca9e.png) 8 | 9 | 10 | You can set the Double-View mode to horizontal or vertical by right-clicking the gripper and using the "Rotate" commands: 11 | ![image](https://cloud.githubusercontent.com/assets/10229320/23313809/e78d5f08-fac7-11e6-9207-95edb3a09582.png) 12 | 13 | 14 | It's recommended to restart Notepad++ after shifting from horizontal to vertical split or vice-versa. 15 | 16 | **ComparePlus Concept** 17 | 18 | ComparePlus (CP) assumes that you would normally want to compare an old version of your work vs. its new version. 19 | CP regards the new file as the (more) important one. Your **focal** file. 20 | 21 | **Compare** 22 | 23 | You can initiate a Compare in three ways: 24 | 25 | **1.** Open multiple files (A, B, C, D, - D is active), press "Set as First to Compare", activate file B and press "Compare". 26 | - File B - *active when you pressed "Compare"* - is regarded as the new file and compared to the old file D (default - see **Settings**). 27 | - The new file is positioned at the right view (default). 28 | 29 | **2.** Open two files (A, B) and press "Compare". 30 | - File B (new) is compared to file A. 31 | 32 | **3.** Open multiple files (A, B, C, D), right-click file D's tab and press "Move to Other View" (Notepad++ is now in Double-View mode). 33 | Press "Compare". 34 | - File D (new, default) is compared to file C. 35 | 36 | **Symbols** 37 | 38 | *Added "+":* The line only exists in **this new file**. IOW: the line has been added to the new file, and does not exist in the old one. 39 | 40 | *Removed "-":* The line does not exist in **the other new file**. IOW: the line has been removed in the new file, and only exists in this old file. 41 | 42 | - The "+" symbol will only appear in the new file, and the "-" symbol will only appear in the old file. 43 | 44 | ![image](https://cloud.githubusercontent.com/assets/10229320/23319986/8870fe70-fae1-11e6-922b-3557f0619cdb.png) 45 | 46 | ** 47 | *NOTE:* 48 | If you uncheck the "Detect Moves" option, the meaning of the "+" and "-" symbols would be as follows: 49 | 50 | *Added "+":* The line exists **in this location only in this new file**. It may be in the old file too but in a different location. 51 | 52 | *Removed "-":* The line does not exist **in this location in the other new file**. It may be in the new file too but in a different location. 53 | ** 54 | 55 | *Moved:* The line appears *once* in the other file and in a different location. 56 | ![image](https://cloud.githubusercontent.com/assets/10229320/23321414/1d565642-fae8-11e6-8aad-f7e3d5921f00.png) 57 | 58 | *Moved-Multiple:* The line appears *multiple times* in the other file and in different locations. 59 | 60 | *Changed:* Most of the line is identical in both files. Some changes have been made. 61 | ![image](https://cloud.githubusercontent.com/assets/10229320/23321717/449eb086-fae9-11e6-9801-de449da22981.png) 62 | 63 | **Menu** 64 | 65 | *Compare:* Compare all the lines in both files. 66 | 67 | *Compare Selected Lines:* Compare only the selected blocks in both files. 68 | 69 | *Diff since last Save:* Compare the active *modified and currently unsaved* file to its contents when it was last saved to the disk. 70 | 71 | *SVN/Git Diff:* 72 | 73 | **Settings** 74 | 75 | *First is:* Determines whether the file "Set as First to Compare" should be regarded as the old or new file. 76 | 77 | *Old file position:* Determines whether the old file should be positioned at the left or right view (top/bottom in vertical split). 78 | 79 | *Single-view default compare to:* Determines whether the active file in Single-View mode should be compared to its previous or next file (on "Compare" without "Set First"). 80 | 81 | *Warn about encodings mismatch:* Check to display a warning message on trying to compare two files with different encodings (the results might be inaccurate). 82 | 83 | *Prompt to close files on match:* Check to display an option in the "Files Match" message to close the compared files. 84 | 85 | *Align replacements:* If checked, an added (or moved) line in the new file would be aligned with its counterpart removed line in the old file. 86 | 87 | If unchecked, blank lines would be inserted for added/removed/moved lines in both files (*old CP implementation*). 88 | ![image](https://cloud.githubusercontent.com/assets/10229320/23320254/9f1621cc-fae2-11e6-866a-23cd4347ca9d.png) 89 | 90 | *Wrap around diffs:* Determines whether the "Next" command should be enabled on reaching the last diff and go to the first diff. 91 | 92 | *Re-Compare active on Save:* Check to automatically re-Compare the active Compare on saving its files. 93 | 94 | *Go to first diff after re-Compare:* If unchecked, the caret position would not change on re-Compare. 95 | 96 | *Compact Navigation Bar:* 97 | 98 | **Shortcuts** 99 | 100 | The old `Alt+D` has been removed in order to avoid conflict with Windows convention of Alt+LETTER opening the menu. 101 | 102 | You can set your own shortcuts to all CP commands via Notepad++ Settings -> Shortcut Mapper -> Plugin Commands. 103 | 104 | **Icons** 105 | 106 | You can use the excellent **Customize Toolbar** plugin (by Dave) to add, move and remove any toolbar buttons. 107 | *** 108 | **[Requests and Issues-Report](https://github.com/pnedev/comparePlus/issues)** 109 | **Thank you for [Donating](https://www.paypal.com/paypalme/pnedev).** -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ComparePlus plugin for Notepad++ 2 | ------------------------------- 3 | 4 | ComparePlus is a plugin for Notepad++ that allows the user to: 5 | 6 | - Compare two files and show differences side by side 7 | - Compare only parts (selections) of two files 8 | - Find unique lines between two files 9 | - Diff a file against Git (with the help of [libgit2](https://github.com/libgit2/libgit2) ) 10 | - Diff a file against SVN (with the help of [sqlite](https://sqlite.org) ) 11 | - Diff a changed file since it was last saved 12 | - Diff a file or parts of it against clipboard text content 13 | 14 | It is highly customizable, can ignore spaces, empty lines, letter cases, regexes, can find moves and show character diffs. 15 | Several compared file pairs can be active and displayed at the same time. 16 | 17 | 18 | ![ComparePlus_screenshot1](https://user-images.githubusercontent.com/6064913/233389533-02125b89-60a8-451f-984b-dc3bfd1f2fc3.png) 19 | 20 | Build Status 21 | ------------------------------- 22 | 23 | - [![Build status](https://ci.appveyor.com/api/projects/status/github/pnedev/comparePlus?svg=true)](https://ci.appveyor.com/project/pnedev/comparePlus) 24 | 25 | 26 | Installation 27 | ------------------------------- 28 | 29 | ** IMPORTANT NOTE: ** 30 | ** ComparePlus plugin is available for Notepad++ versions above v8.4.2 (included) ** 31 | 32 | To install the plugin automatically use the Notepad++ PluginAdmin dialog (find it in the `Plugins` menu in Notepad++ versions above v8.4.5). 33 | 34 | To install the plugin manually: 35 | 36 | 1. Create `ComparePlus` folder in Notepad++'s plugins installation folder (`%Notepad++_program_folder%\Plugins`). 37 | 2. Copy the contents of the desired ComparePlus [release](https://github.com/pnedev/comparePlus/releases) zip file 38 | into the newly created folder. Please use the correct archive version based on your Notepad++ architecture - x86, x64 or ARM64. 39 | - ComparePlus.dll : The core plugin DLL. 40 | - `libs` sub-folder : Contains the libs libgit2.dll and sqlite.dll needed for the Diff against Git and SVN commands. 41 | 3. Restart Notepad++. 42 | 43 | 44 | ------------------------------- 45 | ** IMPORTANT NOTE: ** 46 | ** This GitHub project is also the home of the latest [source](https://github.com/pnedev/comparePlus/tree/Compare_v2) and [releases](https://github.com/pnedev/comparePlus/releases) of Compare-plugin for Notepad++. ComparePlus is its highly advanced successor and is meant to be its replacement so Compare-plugin will no longer be supported by me ** 47 | 48 | To install Compare-plugin you can either use the Notepad++ PluginAdmin dialog that will do it automatically 49 | or you can do it manually as described in the following steps based on your Notepad++ version: 50 | 51 | v7.6.3 and above: 52 | 53 | 1. Create `ComparePlugin` folder in Notepad++'s plugins installation folder (`%Notepad++_program_folder%\Plugins`). 54 | 2. Copy the contents of the desired Compare-plugin [release](https://github.com/pnedev/comparePlus/releases) zip file 55 | into the newly created folder. Please use the correct archive version based on your Notepad++ architecture - x86 or x64. 56 | - ComparePlugin.dll : The core plugin DLL. 57 | - `ComparePlugin` sub-folder : Contains the libs libgit2.dll and sqlite.dll needed for the Diff against Git and SVN commands. 58 | 3. Restart Notepad++. 59 | 60 | Pre v7.6.0: 61 | 62 | 1. Copy the contents of the desired Compare-plugin [release](https://github.com/pnedev/comparePlus/releases) zip file 63 | into Notepad++'s plugins installation folder (`%Notepad++_program_folder%\Plugins`). 64 | Please use the correct archive version based on your Notepad++ architecture - x86 or x64. 65 | - ComparePlugin.dll : The core plugin DLL. 66 | - ComparePlugin sub-folder : Contains the libs libgit2.dll and sqlite.dll needed for the Diff against Git and SVN commands. 67 | 2. Restart Notepad++. 68 | 69 | 70 | Releases and continuous builds 71 | ------------------------------- 72 | 73 | - [Releases](https://github.com/pnedev/comparePlus/releases) 74 | - [Continuous builds](https://ci.appveyor.com/project/pnedev/comparePlus/history) 75 | 76 | 77 | Manually building ComparePlus 78 | ------------------------------- 79 | 80 | 1. Open [`comparePlus\projects\2022\ComparePlus.vcxproj`](https://github.com/pnedev/comparePlus/blob/master/projects/2022/ComparePlus.vcxproj) 81 | 2. Build ComparePlus plugin like a normal Visual Studio project. Available platforms are x86 (Win32) and x64 for Unicode Release and Debug. ARM64 build is also available. 82 | 3. CMake config is available and tested for the generators MinGW Makefiles, Visual Studio and NMake Makefiles 83 | 84 | 85 | Additional information 86 | ------------------------------- 87 | 88 | - [Contributors](https://github.com/pnedev/comparePlus/graphs/contributors) 89 | - Check also the official [Notepad++ web site](https://notepad-plus-plus.org/). 90 | 91 | 92 | Changelog 93 | ------------------------------- 94 | 95 | See the [`ReleaseNotes.txt`](https://github.com/pnedev/comparePlus/blob/master/ReleaseNotes.txt) 96 | -------------------------------------------------------------------------------- /ReleaseNotes.txt: -------------------------------------------------------------------------------- 1 | ComparePlus Changelog: 2 | ---------------------- 3 | 4 | 5 | 28.02.2024 6 | v1.2.0 7 | 8 | - Update Notepad++ and Scintilla plugin API headers 9 | - Let Notepad++ handle dialogs dark mode 10 | - Allocate diff changes indicator number via Notepad++ API 11 | - Handle 'Replace All' Notepad++ notifications 12 | - Improve diffs post-processing steps (better diffs presentation in some specific cases) 13 | - Fixed bug and improvements in the change detection algo 14 | - Add commands to bookmark diffs 15 | - Add commands to jump to changes positions within changed line 16 | - Add option to ignore folded lines and also allow folding in compare state 17 | - Add 'Ignore Changed Spaces' option, the current 'Ignore Space' is actually the 'Ignore All Spaces' 18 | - Remove "Best Sequence Change Detect" option - does not bring any added value anymore 19 | - Add compare status info type setting 20 | - Make 'Cancel Compare' much more responsive 21 | - Disable auto-recompare if compare took more than 5 seconds 22 | - Add warning message before comparing very large files 23 | - Change Notepad++ status bar compare info implementation (avoids crashes due to TextFX interoperation) 24 | - Save and restore each view caret line color and layer on compare (improves plugins interoperability) 25 | - Fix unwanted selection when activating compared file 26 | - Fix last line alignment and sync 27 | - Fix selection compare zero line alignment 28 | - Restore view properly after selections compare close 29 | - Changes to some menu items names for more clarity 30 | 31 | 32 | 02.10.2022 33 | v1.1.0 34 | 35 | - Update Notepad++ and Scintilla plugin API headers 36 | - Fix possible crash due to multithreading 37 | - Fix margin diff symbols for high DPI displays 38 | - Fix tabs handling if tabs are hidden in Notepad++ 39 | - Fix position and caret glitch when changing files in compare mode 40 | - Improve command line triggered compare so restored session does not interfere 41 | (command line compare syntax is `notepad++ -pluginMessage=compare new_file.txt old_file.txt`) 42 | - Add settings for enabling / disabling toolbar buttons 43 | - Update build to VS2022 44 | - Fix several minor navigation commands and alignment on first line issues 45 | - Update SQLite3 library to v3.39.4 46 | 47 | 48 | 01.09.2022 49 | v1.0.0 50 | 51 | - Initial ComparePlus release 52 | - Based on the latest (to-date) dev state of the old Compare-plugin 53 | - Improved integration with Notepad++ (works only with Notepad++ versions >= 8.4.2) 54 | - Handles Notepad++ Dark Mode (except for NavBar scroller) 55 | - Improved compare algorithm in both accuracy and speed 56 | - Can compare files selections (parts of files) 57 | - Has Find Uniqie commands to find lines that are only present in each file/selection 58 | - Can compare file/selection to clipboard 59 | - Gives compare statistics (diffs/matches count) 60 | - Detects character diffs 61 | - Has various ignore options - spaces, empty lines, case ignore and the advanced ignore regex 62 | - Can filter results to show only diffs and show only compared selections 63 | - Has auto-re-compare on change feature 64 | - Preserves undo history (uses Scintilla annotations to sync views) 65 | - Has various settings to customize behavior (including control over "mark lines as changed" decision) 66 | - Compare progress is more smooth and informative and cancelling ongoing compare is much more responsive 67 | - Has "equalize diffs" feature - try mouse left-clicking on a diff's compare margin (symbol) and the same but holding Ctrl or Shift keys (or both) 68 | - Can run files compare directly when starting Notepad++ from the command line (notepad++ -pluginMessage=compare old_file.txt new_file.txt) 69 | - Has also ARM64 build (except the SVN diff command that depends on external library which doesn't have ARM64 variant) 70 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: Build {build} 2 | image: Visual Studio 2022 3 | 4 | environment: 5 | matrix: 6 | - platform: Win32 7 | - platform: x64 8 | - platform: ARM64 9 | 10 | configuration: 11 | - Release 12 | - Debug 13 | 14 | before_build: 15 | - ps: | 16 | Write-Output "Platform : $env:platform" 17 | Write-Output "Configuration : $env:configuration" 18 | 19 | build: 20 | parallel: true 21 | project: projects\2022\ComparePlus.sln 22 | 23 | after_build: 24 | - cd "%APPVEYOR_BUILD_FOLDER%" 25 | - ps: >- 26 | 27 | Push-AppveyorArtifact "Notepad++\plugins\ComparePlus\ComparePlus.dll" -FileName ComparePlus.dll 28 | 29 | if ($($env:APPVEYOR_REPO_TAG) -eq "true" -and $env:configuration -eq "Release") { 30 | $ZipFileName = "ComparePlus_$($env:APPVEYOR_REPO_TAG_NAME)_$env:platform.zip" 31 | Remove-Item .\Notepad++\plugins\ComparePlus\*.pdb 32 | 7z a $ZipFileName .\Notepad++\plugins\ComparePlus\* 33 | } 34 | 35 | artifacts: 36 | - path: ComparePlus_*.zip 37 | name: releases 38 | -------------------------------------------------------------------------------- /libs/arm64/git2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/libs/arm64/git2.dll -------------------------------------------------------------------------------- /libs/x64/git2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/libs/x64/git2.dll -------------------------------------------------------------------------------- /libs/x64/sqlite3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/libs/x64/sqlite3.dll -------------------------------------------------------------------------------- /libs/x86/git2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/libs/x86/git2.dll -------------------------------------------------------------------------------- /libs/x86/sqlite3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/libs/x86/sqlite3.dll -------------------------------------------------------------------------------- /projects/2022/ComparePlus.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.852 5 | MinimumVisualStudioVersion = 14.0.23107.0 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ComparePlus", "ComparePlus.vcxproj", "{73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Debug|x64 = Debug|x64 12 | Debug|ARM64 = Debug|ARM64 13 | Release|Win32 = Release|Win32 14 | Release|x64 = Release|x64 15 | Release|ARM64 = Release|ARM64 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}.Debug|Win32.Build.0 = Debug|Win32 20 | {73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}.Debug|x64.ActiveCfg = Debug|x64 21 | {73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}.Debug|x64.Build.0 = Debug|x64 22 | {73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}.Debug|ARM64.ActiveCfg = Debug|ARM64 23 | {73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}.Debug|ARM64.Build.0 = Debug|ARM64 24 | {73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}.Release|Win32.ActiveCfg = Release|Win32 25 | {73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}.Release|Win32.Build.0 = Release|Win32 26 | {73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}.Release|x64.ActiveCfg = Release|x64 27 | {73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}.Release|x64.Build.0 = Release|x64 28 | {73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}.Release|ARM64.ActiveCfg = Release|ARM64 29 | {73C0A930-C2F5-45D2-9795-8EFE62E2F4C6}.Release|ARM64.Build.0 = Release|ARM64 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /res/Fluent/ClearCompareFluent.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Fluent/ClearCompareFluent.ico -------------------------------------------------------------------------------- /res/Fluent/CompareFluent.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Fluent/CompareFluent.ico -------------------------------------------------------------------------------- /res/Fluent/CompareLinesFluent.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Fluent/CompareLinesFluent.ico -------------------------------------------------------------------------------- /res/Fluent/DiffsOnlyFluent.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Fluent/DiffsOnlyFluent.ico -------------------------------------------------------------------------------- /res/Fluent/FirstFluent.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Fluent/FirstFluent.ico -------------------------------------------------------------------------------- /res/Fluent/FirstToCompareFluent.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Fluent/FirstToCompareFluent.ico -------------------------------------------------------------------------------- /res/Fluent/FirstToCompareRTLFluent.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Fluent/FirstToCompareRTLFluent.ico -------------------------------------------------------------------------------- /res/Fluent/LastFluent.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Fluent/LastFluent.ico -------------------------------------------------------------------------------- /res/Fluent/NavBarFluent.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Fluent/NavBarFluent.ico -------------------------------------------------------------------------------- /res/Fluent/NextFluent.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Fluent/NextFluent.ico -------------------------------------------------------------------------------- /res/Fluent/PreviousFluent.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Fluent/PreviousFluent.ico -------------------------------------------------------------------------------- /res/FluentDM/ClearCompareFluentDM.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/FluentDM/ClearCompareFluentDM.ico -------------------------------------------------------------------------------- /res/FluentDM/CompareFluentDM.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/FluentDM/CompareFluentDM.ico -------------------------------------------------------------------------------- /res/FluentDM/CompareLinesFluentDM.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/FluentDM/CompareLinesFluentDM.ico -------------------------------------------------------------------------------- /res/FluentDM/DiffsOnlyFluentDM.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/FluentDM/DiffsOnlyFluentDM.ico -------------------------------------------------------------------------------- /res/FluentDM/FirstFluentDM.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/FluentDM/FirstFluentDM.ico -------------------------------------------------------------------------------- /res/FluentDM/FirstToCompareFluentDM.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/FluentDM/FirstToCompareFluentDM.ico -------------------------------------------------------------------------------- /res/FluentDM/FirstToCompareRTLFluentDM.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/FluentDM/FirstToCompareRTLFluentDM.ico -------------------------------------------------------------------------------- /res/FluentDM/LastFluentDM.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/FluentDM/LastFluentDM.ico -------------------------------------------------------------------------------- /res/FluentDM/NavBarFluentDM.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/FluentDM/NavBarFluentDM.ico -------------------------------------------------------------------------------- /res/FluentDM/NextFluentDM.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/FluentDM/NextFluentDM.ico -------------------------------------------------------------------------------- /res/FluentDM/PreviousFluentDM.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/FluentDM/PreviousFluentDM.ico -------------------------------------------------------------------------------- /res/Standard/ClearCompare.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Standard/ClearCompare.bmp -------------------------------------------------------------------------------- /res/Standard/Compare.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Standard/Compare.bmp -------------------------------------------------------------------------------- /res/Standard/CompareDocking.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Standard/CompareDocking.ico -------------------------------------------------------------------------------- /res/Standard/CompareLines.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Standard/CompareLines.bmp -------------------------------------------------------------------------------- /res/Standard/DiffsOnly.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Standard/DiffsOnly.bmp -------------------------------------------------------------------------------- /res/Standard/First.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Standard/First.bmp -------------------------------------------------------------------------------- /res/Standard/FirstToCompare.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Standard/FirstToCompare.bmp -------------------------------------------------------------------------------- /res/Standard/FirstToCompareRTL.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Standard/FirstToCompareRTL.bmp -------------------------------------------------------------------------------- /res/Standard/Last.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Standard/Last.bmp -------------------------------------------------------------------------------- /res/Standard/NavBar.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Standard/NavBar.bmp -------------------------------------------------------------------------------- /res/Standard/Next.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Standard/Next.bmp -------------------------------------------------------------------------------- /res/Standard/Previous.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/res/Standard/Previous.bmp -------------------------------------------------------------------------------- /src/AboutDlg/AboutDialog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "AboutDialog.h" 24 | #include "resource.h" 25 | #include "DockingFeature/Window.h" 26 | 27 | #include "NppHelpers.h" 28 | 29 | 30 | static const TCHAR cDonate_URL[] = TEXT("https://www.paypal.com/paypalme/pnedev"); 31 | static const TCHAR cRepo_URL[] = TEXT("https://github.com/pnedev/comparePlus"); 32 | static const TCHAR cHelp_URL[] = TEXT("https://github.com/pnedev/comparePlus/blob/master/Help.md"); 33 | 34 | 35 | UINT AboutDialog::doDialog() 36 | { 37 | return (UINT)::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_ABOUT_DIALOG), _hParent, 38 | (DLGPROC)dlgProc, (LPARAM)this); 39 | } 40 | 41 | INT_PTR CALLBACK AboutDialog::run_dlgProc(UINT Message, WPARAM wParam, LPARAM /*lParam*/) 42 | { 43 | switch (Message) 44 | { 45 | case WM_INITDIALOG : 46 | { 47 | registerDlgForDarkMode(_hSelf); 48 | 49 | goToCenter(); 50 | 51 | TCHAR buildTimeStr[256]; 52 | 53 | _sntprintf_s(buildTimeStr, _countof(buildTimeStr), _TRUNCATE, 54 | TEXT("Build time: %s, %s"), TEXT(__DATE__), TEXT(__TIME__)); 55 | 56 | ::SetDlgItemText(_hSelf, IDC_BUILD_TIME, buildTimeStr); 57 | 58 | _emailLink.init(_hInst, _hSelf); 59 | _emailLink.create(::GetDlgItem(_hSelf, IDC_EMAIL_LINK), TEXT("mailto:pg.nedev@gmail.com")); 60 | _urlRepo.init(_hInst, _hSelf); 61 | _urlRepo.create(::GetDlgItem(_hSelf, IDC_REPO_URL), cRepo_URL); 62 | _helpLink.init(_hInst, _hSelf); 63 | _helpLink.create(::GetDlgItem(_hSelf, IDC_HELP_URL), cHelp_URL); 64 | 65 | return TRUE; 66 | } 67 | case WM_COMMAND : 68 | { 69 | switch (wParam) 70 | { 71 | case IDC_ABOUT_CLOSE_BUTTON : 72 | case IDCANCEL : 73 | ::EndDialog(_hSelf, 0); 74 | return TRUE; 75 | 76 | case IDC_DONATE_BUTTON : 77 | ::ShellExecute(NULL, _T("open"), cDonate_URL, NULL, NULL, SW_SHOWNORMAL); 78 | return TRUE; 79 | 80 | default : 81 | break; 82 | } 83 | break; 84 | } 85 | } 86 | return FALSE; 87 | } 88 | 89 | -------------------------------------------------------------------------------- /src/AboutDlg/AboutDialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #pragma once 19 | 20 | 21 | #include "PluginInterface.h" 22 | #include "DockingFeature/StaticDialog.h" 23 | #include "URLCtrl.h" 24 | 25 | 26 | class AboutDialog : public StaticDialog 27 | { 28 | 29 | public: 30 | AboutDialog(HINSTANCE hInst, NppData nppDataParam) : StaticDialog() 31 | { 32 | Window::init(hInst, nppDataParam._nppHandle); 33 | }; 34 | 35 | ~AboutDialog() 36 | { 37 | destroy(); 38 | } 39 | 40 | UINT doDialog(); 41 | 42 | virtual void destroy() { 43 | _emailLink.destroy(); 44 | _urlRepo.destroy(); 45 | _helpLink.destroy(); 46 | }; 47 | 48 | 49 | protected : 50 | virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); 51 | 52 | private: 53 | /* for eMail */ 54 | URLCtrl _emailLink; 55 | URLCtrl _urlRepo; 56 | URLCtrl _helpLink; 57 | }; 58 | -------------------------------------------------------------------------------- /src/AboutDlg/URLCtrl.cpp: -------------------------------------------------------------------------------- 1 | //this file is part of notepad++ 2 | //Copyright (C)2003 Don HO ( donho@altern.org ) 3 | // 4 | //This program is free software; you can redistribute it and/or 5 | //modify it under the terms of the GNU General Public License 6 | //as published by the Free Software Foundation; either 7 | //version 2 of the License, or (at your option) any later version. 8 | // 9 | //This program is distributed in the hope that it will be useful, 10 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | //GNU General Public License for more details. 13 | // 14 | //You should have received a copy of the GNU General Public License 15 | //along with this program; if not, write to the Free Software 16 | //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 | 18 | #include "URLCtrl.h" 19 | #include 20 | #include 21 | 22 | static const BYTE XORMask[128] = 23 | { 24 | 0xff, 0xff, 0xff, 0xff, 25 | 0xf9, 0xff, 0xff, 0xff, 26 | 0xf0, 0xff, 0xff, 0xff, 27 | 0xf0, 0xff, 0xff, 0xff, 28 | 0xf0, 0xff, 0xff, 0xff, 29 | 0xf0, 0xff, 0xff, 0xff, 30 | 0xf0, 0x24, 0xff, 0xff, 31 | 0xf0, 0x00, 0x7f, 0xff, 32 | 0xc0, 0x00, 0x7f, 0xff, 33 | 0x80, 0x00, 0x7f, 0xff, 34 | 0x80, 0x00, 0x7f, 0xff, 35 | 0x80, 0x00, 0x7f, 0xff, 36 | 0x80, 0x00, 0x7f, 0xff, 37 | 0x80, 0x00, 0x7f, 0xff, 38 | 0xc0, 0x00, 0x7f, 0xff, 39 | 0xe0, 0x00, 0x7f, 0xff, 40 | 0xf0, 0x00, 0xff, 0xff, 41 | 0xf0, 0x00, 0xff, 0xff, 42 | 0xf0, 0x00, 0xff, 0xff, 43 | 0xff, 0xff, 0xff, 0xff, 44 | 0xff, 0xff, 0xff, 0xff, 45 | 0xff, 0xff, 0xff, 0xff, 46 | 0xff, 0xff, 0xff, 0xff, 47 | 0xff, 0xff, 0xff, 0xff, 48 | 0xff, 0xff, 0xff, 0xff, 49 | 0xff, 0xff, 0xff, 0xff, 50 | 0xff, 0xff, 0xff, 0xff, 51 | 0xff, 0xff, 0xff, 0xff, 52 | 0xff, 0xff, 0xff, 0xff, 53 | 0xff, 0xff, 0xff, 0xff, 54 | 0xff, 0xff, 0xff, 0xff, 55 | 0xff, 0xff, 0xff, 0xff, 56 | }; 57 | 58 | /* AND mask for hand cursor */ 59 | /* Generated by HexEdit */ 60 | static const BYTE ANDMask[128] = 61 | { 62 | 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 64 | 0x06, 0x00, 0x00, 0x00, 65 | 0x06, 0x00, 0x00, 0x00, 66 | 0x06, 0x00, 0x00, 0x00, 67 | 0x06, 0x00, 0x00, 0x00, 68 | 0x06, 0x00, 0x00, 0x00, 69 | 0x06, 0xdb, 0x00, 0x00, 70 | 0x06, 0xdb, 0x00, 0x00, 71 | 0x36, 0xdb, 0x00, 0x00, 72 | 0x36, 0xdb, 0x00, 0x00, 73 | 0x37, 0xff, 0x00, 0x00, 74 | 0x3f, 0xff, 0x00, 0x00, 75 | 0x3f, 0xff, 0x00, 0x00, 76 | 0x1f, 0xff, 0x00, 0x00, 77 | 0x0f, 0xff, 0x00, 0x00, 78 | 0x07, 0xfe, 0x00, 0x00, 79 | 0x00, 0x00, 0x00, 0x00, 80 | 0x00, 0x00, 0x00, 0x00, 81 | 0x00, 0x00, 0x00, 0x00, 82 | 0x00, 0x00, 0x00, 0x00, 83 | 0x00, 0x00, 0x00, 0x00, 84 | 0x00, 0x00, 0x00, 0x00, 85 | 0x00, 0x00, 0x00, 0x00, 86 | 0x00, 0x00, 0x00, 0x00, 87 | 0x00, 0x00, 0x00, 0x00, 88 | 0x00, 0x00, 0x00, 0x00, 89 | 0x00, 0x00, 0x00, 0x00, 90 | 0x00, 0x00, 0x00, 0x00, 91 | 0x00, 0x00, 0x00, 0x00, 92 | 0x00, 0x00, 0x00, 0x00, 93 | 0x00, 0x00, 0x00, 0x00, 94 | }; 95 | 96 | 97 | void URLCtrl::create(HWND itemHandle, const TCHAR* link, COLORREF linkColor) 98 | { 99 | // turn on notify style 100 | ::SetWindowLongPtr(itemHandle, GWL_STYLE, ::GetWindowLongPtr(itemHandle, GWL_STYLE) | SS_NOTIFY); 101 | 102 | // set the URL text (not the display text) 103 | if (link) _tcscpy_s(_URL, _countof(_URL), link); 104 | 105 | // set the hyper-link colour 106 | _linkColor = linkColor; 107 | 108 | // set the visited colour 109 | _visitedColor = RGB(128,0,128); 110 | 111 | // subclass the static control 112 | _oldproc = (WNDPROC)::SetWindowLongPtr(itemHandle, GWLP_WNDPROC, reinterpret_cast(URLCtrlProc)); 113 | 114 | // associate the URL structure with the static control 115 | ::SetWindowLongPtr(itemHandle, GWLP_USERDATA, reinterpret_cast(this)); 116 | } 117 | 118 | LRESULT URLCtrl::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) 119 | { 120 | switch(Message) 121 | { 122 | // Free up the structure we allocated 123 | case WM_NCDESTROY: 124 | //HeapFree(GetProcessHeap(), 0, url); 125 | break; 126 | 127 | // Paint the static control using our custom 128 | // colours, and with an underline text style 129 | case WM_PAINT: 130 | { 131 | LONG_PTR dwStyle = ::GetWindowLongPtr(hwnd, GWL_STYLE); 132 | DWORD dwDTStyle = DT_SINGLELINE; 133 | 134 | //Test if centered horizontally or vertically 135 | if (dwStyle & SS_CENTER) dwDTStyle |= DT_CENTER; 136 | if (dwStyle & SS_RIGHT) dwDTStyle |= DT_RIGHT; 137 | if (dwStyle & SS_CENTERIMAGE) dwDTStyle |= DT_VCENTER; 138 | 139 | RECT rect; 140 | ::GetClientRect(hwnd, &rect); 141 | 142 | PAINTSTRUCT ps; 143 | HDC hdc = ::BeginPaint(hwnd, &ps); 144 | 145 | ::SetTextColor(hdc, _linkColor); 146 | ::SetBkColor (hdc, ::GetSysColor(COLOR_3DFACE)); 147 | 148 | // Create an underline font 149 | if(_hfUnderlined == 0) 150 | { 151 | // Get the default GUI font 152 | LOGFONT lf; 153 | HFONT hf = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); 154 | 155 | // Add UNDERLINE attribute 156 | GetObject(hf, sizeof(lf), &lf); 157 | lf.lfUnderline = TRUE; 158 | 159 | // Create a new font 160 | _hfUnderlined = ::CreateFontIndirect(&lf); 161 | } 162 | 163 | HANDLE hOld = SelectObject(hdc, _hfUnderlined); 164 | 165 | // Draw the text! 166 | TCHAR szWinText[MAX_PATH]; 167 | ::GetWindowText(hwnd, szWinText, _countof(szWinText)); 168 | ::DrawText(hdc, szWinText, -1, &rect, dwDTStyle); 169 | 170 | ::SelectObject(hdc, hOld); 171 | 172 | ::EndPaint(hwnd, &ps); 173 | 174 | return 0; 175 | } 176 | 177 | case WM_SETTEXT: 178 | { 179 | LRESULT ret = ::CallWindowProc(_oldproc, hwnd, Message, wParam, lParam); 180 | ::InvalidateRect(hwnd, 0, 0); 181 | return ret; 182 | } 183 | // Provide a hand cursor when the mouse moves over us 184 | //case WM_SETCURSOR: 185 | case WM_MOUSEMOVE: 186 | { 187 | if (_hCursor == 0) 188 | _hCursor = ::CreateCursor(::GetModuleHandle(0), 5, 2, 32, 32, XORMask, ANDMask); 189 | 190 | SetCursor(_hCursor); 191 | return TRUE; 192 | } 193 | 194 | case WM_LBUTTONDOWN: 195 | _clicking = true; 196 | break; 197 | 198 | case WM_LBUTTONUP: 199 | if(_clicking) 200 | { 201 | _clicking = false; 202 | _linkColor = _visitedColor; 203 | 204 | ::InvalidateRect(hwnd, 0, 0); 205 | ::UpdateWindow(hwnd); 206 | 207 | // Open a browser 208 | if(_URL[0]) 209 | { 210 | ::ShellExecute(NULL, TEXT("open"), _URL, NULL, NULL, SW_SHOWNORMAL); 211 | } 212 | else 213 | { 214 | TCHAR szWinText[MAX_PATH]; 215 | ::GetWindowText(hwnd, szWinText, _countof(szWinText)); 216 | ::ShellExecute(NULL, TEXT("open"), szWinText, NULL, NULL, SW_SHOWNORMAL); 217 | } 218 | } 219 | 220 | break; 221 | 222 | // A standard static control returns HTTRANSPARENT here, which 223 | // prevents us from receiving any mouse messages. So, return 224 | // HTCLIENT instead. 225 | case WM_NCHITTEST: 226 | return HTCLIENT; 227 | } 228 | return ::CallWindowProc(_oldproc, hwnd, Message, wParam, lParam); 229 | } 230 | -------------------------------------------------------------------------------- /src/AboutDlg/URLCtrl.h: -------------------------------------------------------------------------------- 1 | //this file is part of notepad++ 2 | //Copyright (C)2003 Don HO ( donho@altern.org ) 3 | // 4 | //This program is free software; you can redistribute it and/or 5 | //modify it under the terms of the GNU General Public License 6 | //as published by the Free Software Foundation; either 7 | //version 2 of the License, or (at your option) any later version. 8 | // 9 | //This program is distributed in the hope that it will be useful, 10 | //but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | //GNU General Public License for more details. 13 | // 14 | //You should have received a copy of the GNU General Public License 15 | //along with this program; if not, write to the Free Software 16 | //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | #include "DockingFeature/Window.h" 23 | #include 24 | 25 | 26 | class URLCtrl : public Window 27 | { 28 | public: 29 | URLCtrl():_hfUnderlined(0),_hCursor(0), _oldproc(NULL), 30 | _linkColor(), _visitedColor(), _clicking(false) { _URL[0] = '\0'; }; 31 | 32 | void create(HWND itemHandle, const TCHAR* link, COLORREF linkColor = RGB(0, 0, 255)); 33 | 34 | void destroy() 35 | { 36 | if(_hfUnderlined) 37 | ::DeleteObject(_hfUnderlined); 38 | if(_hCursor) 39 | ::DestroyCursor(_hCursor); 40 | }; 41 | 42 | private : 43 | TCHAR _URL[MAX_PATH]; 44 | HFONT _hfUnderlined; 45 | HCURSOR _hCursor; 46 | 47 | WNDPROC _oldproc; 48 | COLORREF _linkColor; 49 | COLORREF _visitedColor; 50 | 51 | bool _clicking; 52 | 53 | static LRESULT CALLBACK URLCtrlProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) 54 | { 55 | return ((URLCtrl *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)))->runProc(hwnd, Message, wParam, lParam); 56 | }; 57 | 58 | LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); 59 | }; 60 | -------------------------------------------------------------------------------- /src/Compare.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | #include "Notepad_plus_msgs.h" 27 | #include "Scintilla.h" 28 | #include "menuCmdID.h" 29 | #include "PluginInterface.h" 30 | #include "UserSettings.h" 31 | 32 | 33 | #ifdef DLOG 34 | 35 | #include 36 | #include 37 | 38 | #define LOG_ALGO (1 << 0) 39 | #define LOG_SYNC (1 << 1) 40 | #define LOG_NOTIF (1 << 2) 41 | #define LOG_VISIT (1 << 3) 42 | #define LOG_CHANGE_ALGO (1 << 8) 43 | #define LOG_ALL 0xFFFF 44 | 45 | #define LOGD_GET_TIME \ 46 | if (1) { \ 47 | dLogTime_ms = ::GetTickCount(); \ 48 | } 49 | 50 | #define LOGD(LOG_FILTER, STR) \ 51 | if (DLOG & LOG_FILTER) { \ 52 | const DWORD time_ms = ::GetTickCount(); \ 53 | TCHAR file[MAX_PATH]; \ 54 | char fileA[MAX_PATH * 2]; \ 55 | ::SendMessage(nppData._nppHandle, NPPM_GETFILENAME, _countof(file), (LPARAM)file); \ 56 | ::WideCharToMultiByte(CP_UTF8, 0, file, -1, fileA, sizeof(fileA), NULL, NULL); \ 57 | std::string tmp_str { std::to_string(time_ms - dLogTime_ms) }; \ 58 | dLog += tmp_str; \ 59 | if (tmp_str.size() < 5) dLog += " ms\t\t("; \ 60 | else dLog += " ms\t("; \ 61 | tmp_str = fileA; \ 62 | dLog += tmp_str; \ 63 | if (tmp_str.size() < 7) dLog += ")\t\t\t"; \ 64 | else if (tmp_str.size() < 11) dLog += ")\t\t"; \ 65 | else dLog += ")\t"; \ 66 | dLog += (STR); \ 67 | } 68 | 69 | #define LOGDIF(LOG_FILTER, COND, STR) \ 70 | if ((DLOG & LOG_FILTER) && (COND)) \ 71 | LOGD(LOG_FILTER, STR) 72 | 73 | #define LOGDB(LOG_FILTER, BUFFID, STR) \ 74 | if (DLOG & LOG_FILTER) { \ 75 | const DWORD time_ms = ::GetTickCount(); \ 76 | TCHAR file[MAX_PATH]; \ 77 | char fileA[MAX_PATH * 2]; \ 78 | ::SendMessage(nppData._nppHandle, NPPM_GETFULLPATHFROMBUFFERID, BUFFID, (LPARAM)file); \ 79 | ::WideCharToMultiByte(CP_UTF8, 0, ::PathFindFileName(file), -1, fileA, sizeof(fileA), NULL, NULL); \ 80 | std::string tmp_str { std::to_string(time_ms - dLogTime_ms) }; \ 81 | dLog += tmp_str; \ 82 | if (tmp_str.size() < 5) dLog += " ms\t\t("; \ 83 | else dLog += " ms\t("; \ 84 | tmp_str = fileA; \ 85 | dLog += tmp_str; \ 86 | if (tmp_str.size() < 7) dLog += ")\t\t\t"; \ 87 | else if (tmp_str.size() < 11) dLog += ")\t\t"; \ 88 | else dLog += ")\t"; \ 89 | dLog += (STR); \ 90 | } 91 | 92 | #define PRINT_DIFFS(INFO, DIFFS) \ 93 | if (DLOG & LOG_ALGO) { \ 94 | LOGD(LOG_ALGO, INFO "\n"); \ 95 | for (const auto& d: DIFFS) { \ 96 | LOGD(LOG_ALGO, "\t" + std::string((d.type == diff_type::DIFF_IN_1) ? "D1" : \ 97 | (d.type == diff_type::DIFF_IN_2 ? "D2" : "M")) + \ 98 | " off: " + std::to_string(d.off + 1) + " len: " + std::to_string(d.len) + "\n"); \ 99 | } \ 100 | } 101 | 102 | extern std::string dLog; 103 | extern DWORD dLogTime_ms; 104 | 105 | #else 106 | 107 | #define LOGD_GET_TIME 108 | #define LOGD(LOG_FILTER, STR) 109 | #define LOGDIF(LOG_FILTER, COND, STR) 110 | #define LOGDB(LOG_FILTER, BUFFID, STR) 111 | #define PRINT_DIFFS(INFO, DIFFS) 112 | 113 | #endif 114 | 115 | 116 | enum MENU_COMMANDS 117 | { 118 | CMD_SET_FIRST = 0, 119 | CMD_COMPARE, 120 | CMD_COMPARE_SEL, 121 | CMD_FIND_UNIQUE, 122 | CMD_FIND_UNIQUE_SEL, 123 | CMD_CLEAR_ACTIVE, 124 | CMD_CLEAR_ALL, 125 | CMD_SEPARATOR_1, 126 | CMD_LAST_SAVE_DIFF, 127 | CMD_CLIPBOARD_DIFF, 128 | CMD_SVN_DIFF, 129 | CMD_GIT_DIFF, 130 | CMD_SEPARATOR_2, 131 | CMD_BOOKMARK_DIFFS, 132 | CMD_BOOKMARK_ADD_REM, 133 | CMD_BOOKMARK_CHANGED, 134 | CMD_SEPARATOR_3, 135 | CMD_COMPARE_SUMMARY, 136 | CMD_SEPARATOR_4, 137 | CMD_COMPARE_OPTIONS, 138 | CMD_SEPARATOR_5, 139 | CMD_SHOW_ONLY_DIFF, 140 | CMD_SHOW_ONLY_SEL, 141 | CMD_NAV_BAR, 142 | CMD_SEPARATOR_6, 143 | CMD_AUTO_RECOMPARE, 144 | CMD_SEPARATOR_7, 145 | CMD_PREV, 146 | CMD_NEXT, 147 | CMD_FIRST, 148 | CMD_LAST, 149 | CMD_PREV_CHANGE_POS, 150 | CMD_NEXT_CHANGE_POS, 151 | CMD_SEPARATOR_8, 152 | CMD_SETTINGS, 153 | CMD_SEPARATOR_9, 154 | CMD_ABOUT, 155 | NB_MENU_COMMANDS 156 | }; 157 | 158 | 159 | extern const TCHAR PLUGIN_NAME[]; 160 | 161 | extern NppData nppData; 162 | extern SciFnDirect sciFunc; 163 | extern sptr_t sciPtr[2]; 164 | 165 | extern UserSettings Settings; 166 | 167 | 168 | inline LRESULT CallScintilla(int viewNum, unsigned int uMsg, uptr_t wParam, sptr_t lParam) 169 | { 170 | #ifndef NDEBUG 171 | assert(viewNum >= 0 && viewNum < 2); 172 | #endif 173 | 174 | return sciFunc(sciPtr[viewNum], uMsg, wParam, lParam); 175 | } 176 | 177 | 178 | void ToggleNavigationBar(); 179 | -------------------------------------------------------------------------------- /src/Compare.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pnedev/comparePlus/356d1ce112085150313b4668699731537486de9f/src/Compare.rc -------------------------------------------------------------------------------- /src/CompareOptionsDlg/CompareOptionsDialog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #pragma comment (lib, "uxtheme") 19 | 20 | 21 | #include "CompareOptionsDialog.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "NppHelpers.h" 29 | 30 | 31 | UINT CompareOptionsDialog::doDialog(UserSettings* settings) 32 | { 33 | _Settings = settings; 34 | 35 | return (UINT)::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_COMPARE_OPTIONS_DIALOG), _hParent, 36 | (DLGPROC)dlgProc, (LPARAM)this); 37 | } 38 | 39 | 40 | INT_PTR CALLBACK CompareOptionsDialog::run_dlgProc(UINT Message, WPARAM wParam, LPARAM) 41 | { 42 | switch (Message) 43 | { 44 | case WM_INITDIALOG: 45 | { 46 | registerDlgForDarkMode(_hSelf); 47 | 48 | goToCenter(); 49 | 50 | ::EnableThemeDialogTexture(_hSelf, ETDT_ENABLETAB); 51 | 52 | SetParams(); 53 | } 54 | break; 55 | 56 | case WM_COMMAND: 57 | { 58 | switch (wParam) 59 | { 60 | case IDOK: 61 | if (GetParams()) 62 | { 63 | _Settings->markAsDirty(); 64 | ::EndDialog(_hSelf, IDOK); 65 | 66 | return TRUE; 67 | } 68 | break; 69 | 70 | case IDCANCEL: 71 | ::EndDialog(_hSelf, IDCANCEL); 72 | return TRUE; 73 | 74 | case IDC_IGNORE_CHANGED_SPACES: 75 | { 76 | bool ignoreChangedSpaces = 77 | (Button_GetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_CHANGED_SPACES)) == BST_CHECKED); 78 | 79 | if (ignoreChangedSpaces) 80 | Button_SetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_ALL_SPACES), BST_UNCHECKED); 81 | } 82 | break; 83 | 84 | case IDC_IGNORE_ALL_SPACES: 85 | { 86 | bool ignoreAllSpaces = 87 | (Button_GetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_ALL_SPACES)) == BST_CHECKED); 88 | 89 | if (ignoreAllSpaces) 90 | Button_SetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_CHANGED_SPACES), BST_UNCHECKED); 91 | } 92 | break; 93 | 94 | case IDC_IGNORE_REGEX: 95 | { 96 | bool ignoreRegex = (Button_GetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_REGEX)) == BST_CHECKED); 97 | 98 | Button_Enable(::GetDlgItem(_hSelf, IDC_REGEX_MODE_IGNORE), ignoreRegex); 99 | Button_Enable(::GetDlgItem(_hSelf, IDC_REGEX_MODE_MATCH), ignoreRegex); 100 | 101 | Edit_Enable(::GetDlgItem(_hSelf, IDC_IGNORE_REGEX_STR), ignoreRegex); 102 | } 103 | break; 104 | 105 | default: 106 | return FALSE; 107 | } 108 | } 109 | break; 110 | } 111 | 112 | return FALSE; 113 | } 114 | 115 | 116 | void CompareOptionsDialog::SetParams() 117 | { 118 | Button_SetCheck(::GetDlgItem(_hSelf, IDC_DETECT_MOVES), _Settings->DetectMoves ? BST_CHECKED : BST_UNCHECKED); 119 | Button_SetCheck(::GetDlgItem(_hSelf, IDC_DETECT_CHAR_DIFFS), 120 | _Settings->DetectCharDiffs ? BST_CHECKED : BST_UNCHECKED); 121 | Button_SetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_EMPTY_LINES), 122 | _Settings->IgnoreEmptyLines ? BST_CHECKED : BST_UNCHECKED); 123 | Button_SetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_FOLDED_LINES), 124 | _Settings->IgnoreFoldedLines ? BST_CHECKED : BST_UNCHECKED); 125 | Button_SetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_CHANGED_SPACES), 126 | !_Settings->IgnoreAllSpaces && _Settings->IgnoreChangedSpaces ? BST_CHECKED : BST_UNCHECKED); 127 | Button_SetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_ALL_SPACES), 128 | _Settings->IgnoreAllSpaces ? BST_CHECKED : BST_UNCHECKED); 129 | Button_SetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_CASE), _Settings->IgnoreCase ? BST_CHECKED : BST_UNCHECKED); 130 | Button_SetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_REGEX), _Settings->IgnoreRegex ? BST_CHECKED : BST_UNCHECKED); 131 | 132 | Button_SetCheck(::GetDlgItem(_hSelf, IDC_REGEX_MODE_IGNORE), !_Settings->InvertRegex ? BST_CHECKED : BST_UNCHECKED); 133 | Button_SetCheck(::GetDlgItem(_hSelf, IDC_REGEX_MODE_MATCH), _Settings->InvertRegex ? BST_CHECKED : BST_UNCHECKED); 134 | 135 | Button_Enable(::GetDlgItem(_hSelf, IDC_REGEX_MODE_IGNORE), _Settings->IgnoreRegex); 136 | Button_Enable(::GetDlgItem(_hSelf, IDC_REGEX_MODE_MATCH), _Settings->IgnoreRegex); 137 | 138 | HWND hCtrl = ::GetDlgItem(_hSelf, IDC_IGNORE_REGEX_STR); 139 | 140 | ::SendMessage(hCtrl, EM_SETLIMITTEXT, cMaxRegexLen, 0); 141 | 142 | Edit_SetText(hCtrl, _Settings->IgnoreRegexStr.c_str()); 143 | Edit_Enable(hCtrl, _Settings->IgnoreRegex); 144 | } 145 | 146 | 147 | bool CompareOptionsDialog::GetParams() 148 | { 149 | _Settings->DetectMoves = (Button_GetCheck(::GetDlgItem(_hSelf, IDC_DETECT_MOVES)) == BST_CHECKED); 150 | _Settings->DetectCharDiffs = (Button_GetCheck(::GetDlgItem(_hSelf, IDC_DETECT_CHAR_DIFFS)) == BST_CHECKED); 151 | _Settings->IgnoreEmptyLines = (Button_GetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_EMPTY_LINES)) == BST_CHECKED); 152 | _Settings->IgnoreFoldedLines = (Button_GetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_FOLDED_LINES)) == BST_CHECKED); 153 | _Settings->IgnoreChangedSpaces = (Button_GetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_CHANGED_SPACES)) == BST_CHECKED); 154 | _Settings->IgnoreAllSpaces = (Button_GetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_ALL_SPACES)) == BST_CHECKED); 155 | _Settings->IgnoreCase = (Button_GetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_CASE)) == BST_CHECKED); 156 | _Settings->IgnoreRegex = (Button_GetCheck(::GetDlgItem(_hSelf, IDC_IGNORE_REGEX)) == BST_CHECKED); 157 | 158 | if (_Settings->IgnoreRegex) 159 | { 160 | HWND hCtrl = ::GetDlgItem(_hSelf, IDC_IGNORE_REGEX_STR); 161 | 162 | int len = Edit_LineLength(hCtrl, 0); 163 | 164 | if (len > 0) 165 | { 166 | wchar_t buf[cMaxRegexLen + 1]; 167 | 168 | Edit_GetLine(hCtrl, 0, buf, cMaxRegexLen); 169 | buf[len] = L'\0'; 170 | 171 | if (isRegexValid(buf)) 172 | { 173 | _Settings->IgnoreRegexStr = buf; 174 | } 175 | else 176 | { 177 | ::SetFocus(hCtrl); 178 | 179 | return false; 180 | } 181 | } 182 | else 183 | { 184 | _Settings->IgnoreRegexStr = L""; 185 | } 186 | 187 | _Settings->InvertRegex = (Button_GetCheck(::GetDlgItem(_hSelf, IDC_REGEX_MODE_MATCH)) == BST_CHECKED); 188 | } 189 | 190 | return true; 191 | } 192 | 193 | 194 | bool CompareOptionsDialog::isRegexValid(const wchar_t* regexStr) 195 | { 196 | try 197 | { 198 | std::wregex testRegex(regexStr, std::regex::ECMAScript); 199 | } 200 | catch (std::regex_error& err) 201 | { 202 | ::MessageBoxA(nppData._nppHandle, err.what(), "ComparePlus Bad Regex", MB_OK | MB_ICONWARNING); 203 | 204 | return false; 205 | } 206 | 207 | return true; 208 | } 209 | -------------------------------------------------------------------------------- /src/CompareOptionsDlg/CompareOptionsDialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #pragma once 19 | 20 | 21 | #include "PluginInterface.h" 22 | #include "DockingFeature/StaticDialog.h" 23 | #include "resource.h" 24 | #include "UserSettings.h" 25 | 26 | 27 | using namespace std; 28 | 29 | 30 | class CompareOptionsDialog : public StaticDialog 31 | { 32 | 33 | public: 34 | CompareOptionsDialog(HINSTANCE hInst, NppData nppDataParam) : StaticDialog() 35 | { 36 | _nppData = nppDataParam; 37 | Window::init(hInst, nppDataParam._nppHandle); 38 | }; 39 | 40 | ~CompareOptionsDialog() 41 | { 42 | destroy(); 43 | } 44 | 45 | UINT doDialog(UserSettings* settings); 46 | 47 | virtual void destroy() {}; 48 | 49 | protected : 50 | INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam); 51 | 52 | void SetParams(); 53 | bool GetParams(); 54 | 55 | private: 56 | static constexpr int cMaxRegexLen = 1023; 57 | 58 | bool isRegexValid(const wchar_t* regexStr); 59 | 60 | /* Handles */ 61 | NppData _nppData; 62 | 63 | struct UserSettings* _Settings; 64 | }; 65 | -------------------------------------------------------------------------------- /src/Engine/Engine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C)2011 Jean-Sebastien Leroy (jean.sebastien.leroy@gmail.com) 4 | * Copyright (C)2017-2022 Pavel Nedev (pg.nedev@gmail.com) 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "Compare.h" 31 | #include "NppHelpers.h" 32 | 33 | 34 | enum class CompareResult 35 | { 36 | COMPARE_ERROR, 37 | COMPARE_CANCELLED, 38 | COMPARE_MATCH, 39 | COMPARE_MISMATCH 40 | }; 41 | 42 | 43 | struct section_t 44 | { 45 | section_t() : off(0), len(0) {} 46 | section_t(intptr_t o, intptr_t l) : off(o), len(l) {} 47 | 48 | intptr_t off; 49 | intptr_t len; 50 | }; 51 | 52 | 53 | struct CompareOptions 54 | { 55 | CompareOptions() 56 | { 57 | selections[0] = std::make_pair(-1, -1); 58 | selections[1] = std::make_pair(-1, -1); 59 | } 60 | 61 | inline void setIgnoreRegex(const std::wstring& regexStr, bool invert) 62 | { 63 | if (!regexStr.empty()) 64 | { 65 | ignoreRegex = std::make_unique(regexStr, std::regex::ECMAScript | std::regex::optimize); 66 | invertRegex = invert; 67 | } 68 | else 69 | { 70 | ignoreRegex = nullptr; 71 | } 72 | } 73 | 74 | inline void clearIgnoreRegex() 75 | { 76 | ignoreRegex = nullptr; 77 | } 78 | 79 | int newFileViewId; 80 | 81 | bool findUniqueMode; 82 | 83 | bool alignAllMatches; 84 | bool neverMarkIgnored; 85 | bool detectMoves; 86 | bool detectCharDiffs; 87 | bool ignoreEmptyLines; 88 | bool ignoreFoldedLines; 89 | bool ignoreChangedSpaces; 90 | bool ignoreAllSpaces; 91 | bool ignoreCase; 92 | 93 | bool recompareOnChange; 94 | 95 | std::unique_ptr ignoreRegex; 96 | bool invertRegex; 97 | 98 | int changedThresholdPercent; 99 | 100 | bool selectionCompare; 101 | 102 | std::pair selections[2]; 103 | }; 104 | 105 | 106 | struct AlignmentViewData 107 | { 108 | intptr_t line {0}; 109 | int diffMask {0}; 110 | }; 111 | 112 | 113 | struct AlignmentPair 114 | { 115 | AlignmentViewData main; 116 | AlignmentViewData sub; 117 | }; 118 | 119 | 120 | using AlignmentInfo_t = std::vector; 121 | 122 | 123 | struct CompareSummary 124 | { 125 | inline void clear() 126 | { 127 | diffLines = 0; 128 | added = 0; 129 | removed = 0; 130 | moved = 0; 131 | changed = 0; 132 | match = 0; 133 | 134 | alignmentInfo.clear(); 135 | } 136 | 137 | intptr_t diffLines; 138 | intptr_t added; 139 | intptr_t removed; 140 | intptr_t moved; 141 | intptr_t changed; 142 | intptr_t match; 143 | 144 | AlignmentInfo_t alignmentInfo; 145 | }; 146 | 147 | 148 | CompareResult compareViews(const CompareOptions& options, const TCHAR* progressInfo, CompareSummary& summary); 149 | -------------------------------------------------------------------------------- /src/Engine/varray.h: -------------------------------------------------------------------------------- 1 | /* varray - a variable size array implemented with std::vector */ 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | 8 | template 9 | struct varray 10 | { 11 | public: 12 | varray() {} 13 | ~varray() {} 14 | 15 | // Be very careful when using the returned Elem reference! It may become invalid on consecutive calls to get() 16 | // because the vector memory might be reallocated! 17 | inline Elem& get(size_t i) 18 | { 19 | if (_buf.size() <= i) 20 | _buf.resize(i + 1, { 0 }); 21 | 22 | return _buf[i]; 23 | } 24 | 25 | inline std::vector& get() 26 | { 27 | return _buf; 28 | } 29 | 30 | private: 31 | std::vector _buf; 32 | }; 33 | -------------------------------------------------------------------------------- /src/Icons/icon_added.h: -------------------------------------------------------------------------------- 1 | /* RGBA */ 2 | static const unsigned char icon_added[] = { 3 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0xFF, 0x00, 0x9F, 0x00, 0xFF, 10 | 0x00, 0x9F, 0x00, 0xFF, 0x00, 0x94, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x9D, 0x00, 0xFF, 0x3E, 0xB9, 0x3E, 0xFF, 0x3E, 0xB9, 0x3E, 0xFF, 15 | 0x00, 0x9D, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x00, 0xFF, 19 | 0x6A, 0xB7, 0x6A, 0xFF, 0x6A, 0xB7, 0x6A, 0xFF, 0x00, 0x9B, 0x00, 0xFF, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0xFF, 0x39, 0xB7, 0x39, 0xFF, 24 | 0x39, 0xB7, 0x39, 0xFF, 0x00, 0x99, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x00, 0xFF, 27 | 0x00, 0x96, 0x00, 0xFF, 0x00, 0x96, 0x00, 0xFF, 0x00, 0x96, 0x00, 0xFF, 28 | 0x00, 0x96, 0x00, 0xFF, 0x00, 0xAE, 0x00, 0xFF, 0x00, 0xAE, 0x00, 0xFF, 29 | 0x00, 0x96, 0x00, 0xFF, 0x00, 0x96, 0x00, 0xFF, 0x00, 0x96, 0x00, 0xFF, 30 | 0x00, 0x96, 0x00, 0xFF, 0x00, 0x8D, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 31 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, 0xFF, 0x11, 0xB0, 0x11, 0xFF, 32 | 0x00, 0xA6, 0x00, 0xFF, 0x00, 0x9F, 0x00, 0xFF, 0x00, 0x9F, 0x00, 0xFF, 33 | 0x00, 0x96, 0x00, 0xFF, 0x00, 0x96, 0x00, 0xFF, 0x00, 0x9F, 0x00, 0xFF, 34 | 0x00, 0x9F, 0x00, 0xFF, 0x00, 0xA6, 0x00, 0xFF, 0x11, 0xB0, 0x11, 0xFF, 35 | 0x00, 0x92, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x8B, 0x00, 0xFF, 0x00, 0xA8, 0x00, 0xFF, 0x00, 0x94, 0x00, 0xFF, 37 | 0x00, 0x8C, 0x00, 0xFF, 0x00, 0x84, 0x00, 0xFF, 0x00, 0x79, 0x00, 0xFF, 38 | 0x00, 0x79, 0x00, 0xFF, 0x00, 0x84, 0x00, 0xFF, 0x00, 0x8C, 0x00, 0xFF, 39 | 0x00, 0x94, 0x00, 0xFF, 0x00, 0xA8, 0x00, 0xFF, 0x00, 0x8B, 0x00, 0xFF, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xFF, 41 | 0x00, 0x78, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 42 | 0x00, 0x78, 0x00, 0xFF, 0x00, 0x6C, 0x00, 0xFF, 0x00, 0x6C, 0x00, 0xFF, 43 | 0x00, 0x78, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 44 | 0x00, 0x78, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x00, 0xFF, 47 | 0x00, 0x78, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 0x00, 0x6F, 0x00, 0xFF, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x00, 0xFF, 0x00, 0x75, 0x00, 0xFF, 52 | 0x00, 0x75, 0x00, 0xFF, 0x00, 0x6C, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 | 0x00, 0x66, 0x00, 0xFF, 0x00, 0x8B, 0x00, 0xFF, 0x00, 0x8B, 0x00, 0xFF, 57 | 0x00, 0x66, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x00, 0xFF, 61 | 0x00, 0x5E, 0x00, 0xFF, 0x00, 0x5E, 0x00, 0xFF, 0x00, 0x5E, 0x00, 0xFF, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 68 | 0x00, 0x00, 0x00, 0x00 69 | }; 70 | 71 | 72 | static const unsigned char icon_added_local[] = { 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 79 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 80 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 81 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 82 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 83 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0xFF, 0x00, 0x9F, 0x00, 0xFF, 84 | 0x00, 0x9F, 0x00, 0xFF, 0x00, 0x94, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 85 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 87 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 88 | 0x00, 0x9D, 0x00, 0xFF, 0x3E, 0xB9, 0x3E, 0xFF, 0x3E, 0xB9, 0x3E, 0xFF, 89 | 0x00, 0x9D, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 90 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 91 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 92 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x00, 0xFF, 93 | 0x6A, 0xB7, 0x6A, 0xFF, 0x6A, 0xB7, 0x6A, 0xFF, 0x00, 0x9B, 0x00, 0xFF, 94 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 95 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 96 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x00, 0xFF, 0x00, 0x96, 0x00, 0xFF, 97 | 0x00, 0x96, 0x00, 0xFF, 0x00, 0x96, 0x00, 0xFF, 0x00, 0xAE, 0x00, 0xFF, 98 | 0x00, 0xAE, 0x00, 0xFF, 0x00, 0x96, 0x00, 0xFF, 0x00, 0x96, 0x00, 0xFF, 99 | 0x00, 0x96, 0x00, 0xFF, 0x00, 0x8D, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 100 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 101 | 0x00, 0x92, 0x00, 0xFF, 0x11, 0xB0, 0x11, 0xFF, 0x00, 0xA6, 0x00, 0xFF, 102 | 0x00, 0x9F, 0x00, 0xFF, 0x00, 0x96, 0x00, 0xFF, 0x00, 0x96, 0x00, 0xFF, 103 | 0x00, 0x9F, 0x00, 0xFF, 0x00, 0xA6, 0x00, 0xFF, 0x11, 0xB0, 0x11, 0xFF, 104 | 0x00, 0x92, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 105 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x00, 0xFF, 106 | 0x00, 0xA8, 0x00, 0xFF, 0x00, 0x94, 0x00, 0xFF, 0x00, 0x84, 0x00, 0xFF, 107 | 0x00, 0x79, 0x00, 0xFF, 0x00, 0x79, 0x00, 0xFF, 0x00, 0x84, 0x00, 0xFF, 108 | 0x00, 0x94, 0x00, 0xFF, 0x00, 0xA8, 0x00, 0xFF, 0x00, 0x8B, 0x00, 0xFF, 109 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 110 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 111 | 0x00, 0x78, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 0x00, 0x6C, 0x00, 0xFF, 112 | 0x00, 0x6C, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 113 | 0x00, 0x78, 0x00, 0xFF, 0x00, 0x78, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 114 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 115 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 116 | 0x00, 0x6C, 0x00, 0xFF, 0x00, 0x75, 0x00, 0xFF, 0x00, 0x75, 0x00, 0xFF, 117 | 0x00, 0x6C, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 118 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0xFF, 119 | 0x00, 0x84, 0x00, 0xFF, 0x00, 0x84, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 120 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0xFF, 121 | 0x00, 0x8B, 0x00, 0xFF, 0x00, 0x8B, 0x00, 0xFF, 0x00, 0x66, 0x00, 0xFF, 122 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 123 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xFF, 0x00, 0xAE, 0x00, 0xFF, 124 | 0x00, 0x78, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 125 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x00, 0xFF, 0x00, 0x5E, 0x00, 0xFF, 126 | 0x00, 0x5E, 0x00, 0xFF, 0x00, 0x5E, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 127 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 128 | 0x00, 0x6C, 0x00, 0xFF, 0x00, 0x6C, 0x00, 0xFF, 0x00, 0x6C, 0x00, 0xFF, 129 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 130 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 131 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 132 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 133 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 134 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 135 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 136 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 137 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 138 | 0x00, 0x00, 0x00, 0x00 139 | }; 140 | -------------------------------------------------------------------------------- /src/Icons/icon_changed.h: -------------------------------------------------------------------------------- 1 | /* RGBA */ 2 | static const unsigned char icon_changed[] = { 3 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0xAE, 0x00, 0x1D, 0x14, 0xDD, 0x00, 0x25, 0xF8, 11 | 0xF7, 0x00, 0x28, 0xFF, 0xCC, 0x00, 0x21, 0x51, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0xD0, 0x00, 0x22, 0x92, 0xFF, 0x53, 0x75, 0xFF, 0xDC, 0x00, 0x23, 0xE3, 16 | 0xAE, 0x00, 0x1D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x2A, 0x1A, 0xFF, 0x00, 0x2A, 0xFD, 20 | 0xFF, 0x1D, 0x47, 0xFF, 0xD8, 0x00, 0x23, 0x56, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 23 | 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 24 | 0xD9, 0x24, 0x15, 0xFF, 0xFF, 0x46, 0x6A, 0xFF, 0xD0, 0x11, 0x1B, 0xFF, 25 | 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x60, 0x00, 0xFF, 27 | 0xFF, 0xA0, 0x4A, 0xFF, 0xFF, 0x82, 0x24, 0xFF, 0xFF, 0x82, 0x24, 0xFF, 28 | 0xFF, 0x82, 0x24, 0xFF, 0xFD, 0x6D, 0x24, 0xFF, 0xFF, 0x00, 0x2B, 0xFF, 29 | 0xFF, 0x09, 0x36, 0xFF, 0xF6, 0x62, 0x24, 0xFF, 0xFF, 0x82, 0x24, 0xFF, 30 | 0xFF, 0xA0, 0x4A, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 31 | 0x00, 0x00, 0x00, 0x00, 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 32 | 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 33 | 0xBB, 0x1A, 0x25, 0xFF, 0xFF, 0x41, 0x64, 0xFF, 0xB4, 0x18, 0x23, 0xFF, 34 | 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 35 | 0x9F, 0x57, 0x2C, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0xD9, 0x00, 0x23, 0x3F, 0xFF, 0x01, 0x2E, 0xFF, 38 | 0xFF, 0x00, 0x2B, 0xFF, 0xD9, 0x00, 0x23, 0x3F, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x60, 0x00, 0xFF, 41 | 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 42 | 0xCA, 0x13, 0x19, 0xFF, 0xFF, 0x3C, 0x60, 0xFF, 0xD1, 0x22, 0x14, 0xFF, 43 | 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 44 | 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0xE1, 0x60, 0x00, 0xFF, 0xFF, 0xA0, 0x4A, 0xFF, 46 | 0xFF, 0x82, 0x24, 0xFF, 0xF2, 0x59, 0x24, 0xFF, 0xFF, 0x0D, 0x39, 0xFF, 47 | 0xF8, 0x02, 0x27, 0xFF, 0xF0, 0x62, 0x23, 0xFF, 0xFF, 0x82, 0x24, 0xFF, 48 | 0xFF, 0x82, 0x24, 0xFF, 0xFF, 0x82, 0x24, 0xFF, 0xFF, 0xA0, 0x4A, 0xFF, 49 | 0xE1, 0x60, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 51 | 0xCB, 0x0A, 0x24, 0xFF, 0xFF, 0x2B, 0x53, 0xFF, 0xB0, 0x27, 0x25, 0xFF, 52 | 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 53 | 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x1F, 0x6E, 0xFF, 0x1A, 0x44, 0xFF, 56 | 0xE3, 0x00, 0x25, 0xF6, 0xDF, 0x00, 0x25, 0x0E, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAE, 0x00, 0x1D, 0x14, 60 | 0xDB, 0x00, 0x23, 0xEC, 0xFF, 0x25, 0x4E, 0xFF, 0xB6, 0x00, 0x1E, 0x7B, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 | 0x00, 0x00, 0x00, 0x00, 0xAE, 0x00, 0x1D, 0x5E, 0xD7, 0x00, 0x23, 0xF1, 65 | 0xAF, 0x00, 0x1D, 0xDC, 0xDE, 0x00, 0x25, 0x02, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 68 | 0x00, 0x00, 0x00, 0x00 69 | }; 70 | 71 | 72 | static const unsigned char icon_changed_local[] = { 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 79 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAE, 0x00, 0x1D, 0x14, 80 | 0xDD, 0x00, 0x25, 0xF8, 0xF7, 0x00, 0x28, 0xFF, 0xCC, 0x00, 0x21, 0x51, 81 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 82 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 83 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 84 | 0x00, 0x00, 0x00, 0x00, 0xD0, 0x00, 0x22, 0x92, 0xFF, 0x53, 0x75, 0xFF, 85 | 0xDC, 0x00, 0x23, 0xE3, 0xAE, 0x00, 0x1D, 0x14, 0x00, 0x00, 0x00, 0x00, 86 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 87 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 88 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x2A, 0x1A, 89 | 0xFF, 0x00, 0x2A, 0xFD, 0xFF, 0x1D, 0x47, 0xFF, 0xD8, 0x00, 0x23, 0x56, 90 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 91 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x60, 0x00, 0xFF, 92 | 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 93 | 0xE1, 0x60, 0x00, 0xFF, 0xD9, 0x24, 0x15, 0xFF, 0xFF, 0x46, 0x6A, 0xFF, 94 | 0xD0, 0x11, 0x1B, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 95 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 96 | 0x00, 0x00, 0x00, 0x00, 0xE1, 0x60, 0x00, 0xFF, 0xFF, 0xA0, 0x4A, 0xFF, 97 | 0xFF, 0x82, 0x24, 0xFF, 0xFF, 0x82, 0x24, 0xFF, 0xFD, 0x6D, 0x24, 0xFF, 98 | 0xFF, 0x00, 0x2B, 0xFF, 0xFF, 0x09, 0x36, 0xFF, 0xF6, 0x62, 0x24, 0xFF, 99 | 0xFF, 0xA0, 0x4A, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 100 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 101 | 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 102 | 0x9F, 0x57, 0x2C, 0xFF, 0xBB, 0x1A, 0x25, 0xFF, 0xFF, 0x41, 0x64, 0xFF, 103 | 0xB4, 0x18, 0x23, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 104 | 0x9F, 0x57, 0x2C, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 105 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 106 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x00, 0x23, 0x3F, 107 | 0xFF, 0x01, 0x2E, 0xFF, 0xFF, 0x00, 0x2B, 0xFF, 0xD9, 0x00, 0x23, 0x3F, 108 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 109 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 110 | 0x00, 0x00, 0x00, 0x00, 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 111 | 0xE1, 0x60, 0x00, 0xFF, 0xCA, 0x13, 0x19, 0xFF, 0xFF, 0x3C, 0x60, 0xFF, 112 | 0xD1, 0x22, 0x14, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 113 | 0xE1, 0x60, 0x00, 0xFF, 0xE1, 0x60, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 114 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 115 | 0xE1, 0x60, 0x00, 0xFF, 0xFF, 0xA0, 0x4A, 0xFF, 0xF2, 0x59, 0x24, 0xFF, 116 | 0xFF, 0x0D, 0x39, 0xFF, 0xF8, 0x02, 0x27, 0xFF, 0xF0, 0x62, 0x23, 0xFF, 117 | 0xFF, 0x82, 0x24, 0xFF, 0xFF, 0x82, 0x24, 0xFF, 0xFF, 0xA0, 0x4A, 0xFF, 118 | 0xE1, 0x60, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 119 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0x57, 0x2C, 0xFF, 120 | 0x9F, 0x57, 0x2C, 0xFF, 0xCB, 0x0A, 0x24, 0xFF, 0xFF, 0x2B, 0x53, 0xFF, 121 | 0xB0, 0x27, 0x25, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 122 | 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 0x9F, 0x57, 0x2C, 0xFF, 123 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 124 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x1F, 0x6E, 125 | 0xFF, 0x1A, 0x44, 0xFF, 0xE3, 0x00, 0x25, 0xF6, 0xDF, 0x00, 0x25, 0x0E, 126 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 127 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 128 | 0xA8, 0x5D, 0x2E, 0xFF, 0xA8, 0x5D, 0x2E, 0xFF, 0xA8, 0x5D, 0x2E, 0xFF, 129 | 0xAE, 0x00, 0x1D, 0x14, 0xDB, 0x00, 0x23, 0xEC, 0xFF, 0x25, 0x4E, 0xFF, 130 | 0xB6, 0x00, 0x1E, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 131 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 132 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x57, 0x2B, 0xFF, 133 | 0xFF, 0x9B, 0x40, 0xFF, 0x9E, 0x57, 0x2B, 0xFF, 0xAE, 0x00, 0x1D, 0x5E, 134 | 0xD7, 0x00, 0x23, 0xF1, 0xAF, 0x00, 0x1D, 0xDC, 0xDE, 0x00, 0x25, 0x02, 135 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 136 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 137 | 0x00, 0x00, 0x00, 0x00, 0x8E, 0x4E, 0x27, 0xFF, 0x8E, 0x4E, 0x27, 0xFF, 138 | 0x8E, 0x4E, 0x27, 0xFF 139 | }; 140 | -------------------------------------------------------------------------------- /src/Icons/icon_removed.h: -------------------------------------------------------------------------------- 1 | /* RGBA */ 2 | static const unsigned char icon_removed[] = { 3 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0xEA, 0x00, 0x00, 0xFF, 0xF4, 0x00, 0x00, 0xFF, 0xF4, 0x00, 0x00, 0xFF, 23 | 0xF4, 0x00, 0x00, 0xFF, 0xF4, 0x00, 0x00, 0xFF, 0xF4, 0x00, 0x00, 0xFF, 24 | 0xF4, 0x00, 0x00, 0xFF, 0xF4, 0x00, 0x00, 0xFF, 0xF4, 0x00, 0x00, 0xFF, 25 | 0xF4, 0x00, 0x00, 0xFF, 0xF4, 0x00, 0x00, 0xFF, 0xEA, 0x00, 0x00, 0xFF, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0xFF, 27 | 0xFF, 0x44, 0x44, 0xFF, 0xFF, 0x69, 0x69, 0xFF, 0xFF, 0x68, 0x68, 0xFF, 28 | 0xFF, 0x68, 0x68, 0xFF, 0xFF, 0x68, 0x68, 0xFF, 0xFF, 0x68, 0x68, 0xFF, 29 | 0xFF, 0x68, 0x68, 0xFF, 0xFF, 0x68, 0x68, 0xFF, 0xFF, 0x69, 0x69, 0xFF, 30 | 0xFF, 0x44, 0x44, 0xFF, 0xE7, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 31 | 0x00, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x00, 0xFF, 0xFF, 0x42, 0x42, 0xFF, 32 | 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x33, 0x33, 0xFF, 33 | 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x33, 0x33, 0xFF, 34 | 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x42, 0x42, 0xFF, 35 | 0xDA, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 | 0xC4, 0x00, 0x00, 0xFF, 0xFF, 0x17, 0x17, 0xFF, 0xDC, 0x00, 0x00, 0xFF, 37 | 0xDC, 0x00, 0x00, 0xFF, 0xDC, 0x00, 0x00, 0xFF, 0xDC, 0x00, 0x00, 0xFF, 38 | 0xDC, 0x00, 0x00, 0xFF, 0xDC, 0x00, 0x00, 0xFF, 0xDC, 0x00, 0x00, 0xFF, 39 | 0xDC, 0x00, 0x00, 0xFF, 0xFF, 0x17, 0x17, 0xFF, 0xC4, 0x00, 0x00, 0xFF, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0xFF, 41 | 0xF3, 0x00, 0x00, 0xFF, 0xF3, 0x00, 0x00, 0xFF, 0xF3, 0x00, 0x00, 0xFF, 42 | 0xF3, 0x00, 0x00, 0xFF, 0xF3, 0x00, 0x00, 0xFF, 0xF3, 0x00, 0x00, 0xFF, 43 | 0xF3, 0x00, 0x00, 0xFF, 0xF3, 0x00, 0x00, 0xFF, 0xF3, 0x00, 0x00, 0xFF, 44 | 0xF3, 0x00, 0x00, 0xFF, 0xA8, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0xFF, 0x99, 0x00, 0x00, 0xFF, 46 | 0x99, 0x00, 0x00, 0xFF, 0x99, 0x00, 0x00, 0xFF, 0x99, 0x00, 0x00, 0xFF, 47 | 0x99, 0x00, 0x00, 0xFF, 0x99, 0x00, 0x00, 0xFF, 0x99, 0x00, 0x00, 0xFF, 48 | 0x99, 0x00, 0x00, 0xFF, 0x99, 0x00, 0x00, 0xFF, 0x99, 0x00, 0x00, 0xFF, 49 | 0x99, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 68 | 0x00, 0x00, 0x00, 0x00 69 | }; 70 | 71 | 72 | static const unsigned char icon_removed_local[] = { 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 79 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 80 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 81 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 82 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 83 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 84 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 85 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 87 | 0xDF, 0x00, 0x00, 0xFF, 0xE9, 0x00, 0x00, 0xFF, 0xE9, 0x00, 0x00, 0xFF, 88 | 0xE9, 0x00, 0x00, 0xFF, 0xE9, 0x00, 0x00, 0xFF, 0xE9, 0x00, 0x00, 0xFF, 89 | 0xE9, 0x00, 0x00, 0xFF, 0xE9, 0x00, 0x00, 0xFF, 0xE9, 0x00, 0x00, 0xFF, 90 | 0xDF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 91 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x00, 0x00, 0xFF, 92 | 0xFC, 0x41, 0x41, 0xFF, 0xFD, 0x64, 0x64, 0xFF, 0xFD, 0x63, 0x63, 0xFF, 93 | 0xFD, 0x63, 0x63, 0xFF, 0xFD, 0x63, 0x63, 0xFF, 0xFD, 0x63, 0x63, 0xFF, 94 | 0xFD, 0x63, 0x63, 0xFF, 0xFC, 0x4B, 0x4B, 0xFF, 0xDC, 0x00, 0x00, 0xFF, 95 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 96 | 0x00, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0xFF, 0xFB, 0x16, 0x16, 0xFF, 97 | 0xD2, 0x00, 0x00, 0xFF, 0xD2, 0x00, 0x00, 0xFF, 0xD2, 0x00, 0x00, 0xFF, 98 | 0xD2, 0x00, 0x00, 0xFF, 0xD2, 0x00, 0x00, 0xFF, 0xD2, 0x00, 0x00, 0xFF, 99 | 0xFB, 0x1C, 0x1C, 0xFF, 0xBB, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 100 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 101 | 0xA0, 0x00, 0x00, 0xFF, 0xE8, 0x00, 0x00, 0xFF, 0xE8, 0x00, 0x00, 0xFF, 102 | 0xE8, 0x00, 0x00, 0xFF, 0xE8, 0x00, 0x00, 0xFF, 0xE8, 0x00, 0x00, 0xFF, 103 | 0xE8, 0x00, 0x00, 0xFF, 0xE8, 0x00, 0x00, 0xFF, 0xE8, 0x00, 0x00, 0xFF, 104 | 0xA0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 105 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0xFF, 106 | 0x87, 0x00, 0x00, 0xFF, 0x87, 0x00, 0x00, 0xFF, 0x87, 0x00, 0x00, 0xFF, 107 | 0x87, 0x00, 0x00, 0xFF, 0x87, 0x00, 0x00, 0xFF, 0x87, 0x00, 0x00, 0xFF, 108 | 0x87, 0x00, 0x00, 0xFF, 0x87, 0x00, 0x00, 0xFF, 0x92, 0x00, 0x00, 0xFF, 109 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 110 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 111 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 112 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 113 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 114 | 0xDF, 0x00, 0x00, 0xFF, 0xDF, 0x00, 0x00, 0xFF, 0xDF, 0x00, 0x00, 0xFF, 115 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 116 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 117 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 118 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0x00, 0x00, 0xFF, 119 | 0xFD, 0x63, 0x63, 0xFF, 0xD0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 120 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 121 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 122 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 123 | 0x00, 0x00, 0x00, 0x00, 0xB5, 0x00, 0x00, 0xFF, 0xB5, 0x00, 0x00, 0xFF, 124 | 0xB5, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 125 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 126 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 127 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 128 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 129 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 130 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 131 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 132 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 133 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 134 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 135 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 136 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 137 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 138 | 0x00, 0x00, 0x00, 0x00 139 | }; 140 | -------------------------------------------------------------------------------- /src/LibGit2/LibGit2Helper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C)2013 Jean-Sebastien Leroy (jean.sebastien.leroy@gmail.com) 4 | * Copyright (C)2017-2022 Pavel Nedev (pg.nedev@gmail.com) 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "LibGit2Helper.h" 25 | #include "Tools.h" 26 | 27 | 28 | namespace 29 | { 30 | 31 | inline bool getDllPath(TCHAR* dllPath, size_t bufLen) 32 | { 33 | HMODULE hPlugin = ::GetModuleHandle(TEXT("ComparePlus.dll")); 34 | if (!hPlugin) 35 | return false; 36 | 37 | ::GetModuleFileName(hPlugin, (LPWSTR)dllPath, (DWORD)bufLen); 38 | ::PathRemoveFileSpec(dllPath); 39 | _tcscat_s(dllPath, bufLen, TEXT("\\libs\\git2.dll")); 40 | 41 | return true; 42 | } 43 | 44 | } 45 | 46 | 47 | bool isGITlibFound() 48 | { 49 | TCHAR dllPath[MAX_PATH]; 50 | 51 | if (getDllPath(dllPath, _countof(dllPath))) 52 | return fileExists(dllPath); 53 | 54 | return false; 55 | } 56 | 57 | 58 | std::unique_ptr LibGit::Inst; 59 | 60 | 61 | std::unique_ptr& LibGit::load() 62 | { 63 | if (Inst) 64 | return Inst; 65 | 66 | TCHAR dllPath[MAX_PATH]; 67 | 68 | if (!getDllPath(dllPath, _countof(dllPath))) 69 | return Inst; 70 | 71 | HMODULE libGit2 = ::LoadLibrary(dllPath); 72 | if (!libGit2) 73 | return Inst; 74 | 75 | Inst.reset(new LibGit); 76 | 77 | Inst->_isInit = true; 78 | 79 | Inst->version = (PGITLIBVERSION)::GetProcAddress(libGit2, "git_libgit2_version"); 80 | if (!Inst->version) 81 | Inst->_isInit = false; 82 | Inst->repository_open_ext = (PGITREPOSITORYOPENEXT)::GetProcAddress(libGit2, "git_repository_open_ext"); 83 | if (!Inst->repository_open_ext) 84 | Inst->_isInit = false; 85 | Inst->repository_workdir = (PGITREPOSITORYWORKDIR)::GetProcAddress(libGit2, "git_repository_workdir"); 86 | if (!Inst->repository_workdir) 87 | Inst->_isInit = false; 88 | Inst->repository_index = (PGITREPOSITORYINDEX)::GetProcAddress(libGit2, "git_repository_index"); 89 | if (!Inst->repository_index) 90 | Inst->_isInit = false; 91 | Inst->index_get_bypath = (PGITINDEXGETBYPATH)::GetProcAddress(libGit2, "git_index_get_bypath"); 92 | if (!Inst->index_get_bypath) 93 | Inst->_isInit = false; 94 | Inst->blob_lookup = (PGITBLOBLOOKUP)::GetProcAddress(libGit2, "git_blob_lookup"); 95 | if (!Inst->blob_lookup) 96 | Inst->_isInit = false; 97 | Inst->blob_filtered_content = (PGITBLOBFILTERCONTENT)::GetProcAddress(libGit2, "git_blob_filtered_content"); 98 | if (!Inst->blob_filtered_content) 99 | Inst->_isInit = false; 100 | Inst->buf_free = (PGITBUFFREE)::GetProcAddress(libGit2, "git_buf_free"); 101 | if (!Inst->buf_free) 102 | Inst->_isInit = false; 103 | Inst->blob_free = (PGITBLOBFREE)::GetProcAddress(libGit2, "git_blob_free"); 104 | if (!Inst->blob_free) 105 | Inst->_isInit = false; 106 | Inst->index_free = (PGITINDEXFREE)::GetProcAddress(libGit2, "git_index_free"); 107 | if (!Inst->index_free) 108 | Inst->_isInit = false; 109 | Inst->repository_free = (PGITREPOSITORYFREE)::GetProcAddress(libGit2, "git_repository_free"); 110 | if (!Inst->repository_free) 111 | Inst->_isInit = false; 112 | 113 | if (Inst->_isInit) 114 | { 115 | int major, minor, rev; 116 | Inst->version(&major, &minor, &rev); 117 | 118 | if ((major > 0) || (major == 0 && minor >= 22)) // Those API functions are introduced after version 0.22 119 | { 120 | Inst->init = (PGITLIBINIT)::GetProcAddress(libGit2, "git_libgit2_init"); 121 | if (!Inst->init) 122 | Inst->_isInit = false; 123 | Inst->shutdown = (PGITLIBSHUTDOWN)::GetProcAddress(libGit2, "git_libgit2_shutdown"); 124 | if (!Inst->shutdown) 125 | Inst->_isInit = false; 126 | 127 | if (Inst->_isInit) 128 | Inst->init(); 129 | } 130 | } 131 | 132 | if (!Inst->_isInit) 133 | Inst.reset(); 134 | 135 | return Inst; 136 | } 137 | -------------------------------------------------------------------------------- /src/LibGit2/LibGit2Helper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C)2013 Jean-Sebastien Leroy (jean.sebastien.leroy@gmail.com) 4 | * Copyright (C)2017 Pavel Nedev (pg.nedev@gmail.com) 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | 25 | typedef struct git_repository git_repository; 26 | typedef struct git_index git_index; 27 | typedef struct git_blob git_blob; 28 | 29 | 30 | typedef struct { 31 | int32_t seconds; 32 | uint32_t nanoseconds; 33 | } git_index_time; 34 | 35 | 36 | typedef struct git_oid { 37 | unsigned char id[20]; 38 | } git_oid; 39 | 40 | 41 | typedef struct git_index_entry { 42 | git_index_time ctime; 43 | git_index_time mtime; 44 | 45 | uint32_t dev; 46 | uint32_t ino; 47 | uint32_t mode; 48 | uint32_t uid; 49 | uint32_t gid; 50 | uint32_t file_size; 51 | 52 | git_oid id; 53 | 54 | uint16_t flags; 55 | uint16_t flags_extended; 56 | 57 | const char *path; 58 | } git_index_entry; 59 | 60 | 61 | typedef struct { 62 | char *ptr; 63 | size_t asize, size; 64 | } git_buf; 65 | 66 | 67 | /** 68 | * \class 69 | * \brief 70 | */ 71 | class LibGit 72 | { 73 | private: 74 | static std::unique_ptr Inst; 75 | 76 | LibGit() {} 77 | 78 | typedef int (*PGITLIBVERSION) (int *major, int *minor, int *rev); 79 | typedef int (*PGITLIBINIT) (void); 80 | typedef int (*PGITLIBSHUTDOWN) (void); 81 | typedef int (*PGITREPOSITORYOPENEXT) (git_repository **out, const char *path, 82 | unsigned int flags, const char *ceiling_dirs); 83 | typedef const char* (*PGITREPOSITORYWORKDIR) (git_repository *repo); 84 | typedef int (*PGITREPOSITORYINDEX) (git_index **out, git_repository *repo); 85 | typedef const git_index_entry* (*PGITINDEXGETBYPATH) (git_index *index, const char *path, int stage); 86 | typedef int (*PGITBLOBLOOKUP) (git_blob **blob, git_repository *repo, const git_oid *id); 87 | typedef int (*PGITBLOBFILTERCONTENT) (git_buf *out, git_blob *blob, const char *as_path, int check_for_bin_data); 88 | typedef void (*PGITBUFFREE) (git_buf *buf); 89 | typedef void (*PGITBLOBFREE) (const git_blob *blob); 90 | typedef void (*PGITINDEXFREE) (git_index *index); 91 | typedef void (*PGITREPOSITORYFREE) (git_repository *repo); 92 | 93 | PGITLIBVERSION version; 94 | PGITLIBINIT init; 95 | PGITLIBSHUTDOWN shutdown; 96 | 97 | bool _isInit; 98 | 99 | public: 100 | static std::unique_ptr& load(); 101 | 102 | ~LibGit() 103 | { 104 | if (_isInit) 105 | shutdown(); 106 | } 107 | 108 | PGITREPOSITORYOPENEXT repository_open_ext; 109 | PGITREPOSITORYWORKDIR repository_workdir; 110 | PGITREPOSITORYINDEX repository_index; 111 | PGITINDEXGETBYPATH index_get_bypath; 112 | PGITBLOBLOOKUP blob_lookup; 113 | PGITBLOBFILTERCONTENT blob_filtered_content; 114 | PGITBUFFREE buf_free; 115 | PGITBLOBFREE blob_free; 116 | PGITINDEXFREE index_free; 117 | PGITREPOSITORYFREE repository_free; 118 | }; 119 | -------------------------------------------------------------------------------- /src/LibHelpers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C)2013 Jean-Sebastien Leroy (jean.sebastien.leroy@gmail.com) 4 | * Copyright (C)2017-2022 Pavel Nedev (pg.nedev@gmail.com) 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "Compare.h" 25 | #include "LibHelpers.h" 26 | #include "SQLite/SqliteHelper.h" 27 | #include "LibGit2/LibGit2Helper.h" 28 | 29 | 30 | namespace // anonymous namespace 31 | { 32 | 33 | void TCharToChar(const wchar_t* src, char* dest, int destCharsCount) 34 | { 35 | ::WideCharToMultiByte(CP_UTF8, 0, src, -1, dest, destCharsCount, NULL, NULL); 36 | } 37 | 38 | 39 | void RelativePath(const char* fullFilePath, const char* baseDir, char* filePath, unsigned filePathSize) 40 | { 41 | filePath[0] = 0; 42 | 43 | char fullPath[MAX_PATH]; 44 | 45 | strcpy_s(fullPath, _countof(fullPath), fullFilePath); 46 | for (int i = static_cast(strlen(fullPath) - 1); i >= 0; --i) 47 | { 48 | if (fullPath[i] == '\\') 49 | fullPath[i] = '/'; 50 | } 51 | 52 | char basePath[MAX_PATH]; 53 | 54 | strcpy_s(basePath, sizeof(basePath), baseDir); 55 | for (int i = static_cast(strlen(basePath) - 1); i >= 0; --i) 56 | { 57 | if (basePath[i] == '\\') 58 | basePath[i] = '/'; 59 | } 60 | 61 | int relativePathPos = static_cast(strlen(basePath)); 62 | 63 | if (!strncmp(fullPath, basePath, relativePathPos)) 64 | { 65 | if (fullPath[relativePathPos] == '/') 66 | ++relativePathPos; 67 | 68 | strcpy_s(filePath, filePathSize, &fullPath[relativePathPos]); 69 | } 70 | } 71 | 72 | 73 | void RelativePath(const wchar_t* fullFilePath, const wchar_t* baseDir, wchar_t* filePath, unsigned filePathSize) 74 | { 75 | filePath[0] = 0; 76 | 77 | wchar_t fullPath[MAX_PATH]; 78 | 79 | wcscpy_s(fullPath, _countof(fullPath), fullFilePath); 80 | for (int i = static_cast(wcslen(fullPath) - 1); i >= 0; --i) 81 | { 82 | if (fullPath[i] == L'\\') 83 | fullPath[i] = L'/'; 84 | } 85 | 86 | wchar_t basePath[MAX_PATH]; 87 | 88 | wcscpy_s(basePath, _countof(basePath), baseDir); 89 | for (int i = static_cast(wcslen(basePath) - 1); i >= 0; --i) 90 | { 91 | if (basePath[i] == L'\\') 92 | basePath[i] = L'/'; 93 | } 94 | 95 | int relativePathPos = static_cast(wcslen(basePath)); 96 | 97 | if (!wcsncmp(fullPath, basePath, relativePathPos)) 98 | { 99 | if (fullPath[relativePathPos] == L'/') 100 | ++relativePathPos; 101 | 102 | wcscpy_s(filePath, filePathSize, &fullPath[relativePathPos]); 103 | } 104 | } 105 | 106 | 107 | // Search recursively upwards for the dirName folder 108 | bool LocateDirUp(const TCHAR* dirName, const TCHAR* currentDir, TCHAR* fullDirPath, unsigned fullDirPathSize) 109 | { 110 | TCHAR testPath[MAX_PATH]; 111 | 112 | _tcscpy_s(fullDirPath, fullDirPathSize, currentDir); 113 | 114 | while (true) 115 | { 116 | ::PathCombine(testPath, fullDirPath, dirName); 117 | if (::PathIsDirectory(testPath)) 118 | return true; 119 | 120 | if (::PathIsRoot(fullDirPath)) 121 | break; 122 | 123 | // up one folder 124 | ::PathCombine(testPath, fullDirPath, TEXT("..")); 125 | _tcscpy_s(fullDirPath, fullDirPathSize, testPath); 126 | } 127 | 128 | return false; 129 | } 130 | 131 | } // anonymous namespace 132 | 133 | 134 | bool GetSvnFile(const TCHAR* fullFilePath, TCHAR* svnFile, unsigned svnFileSize) 135 | { 136 | TCHAR svnTop[MAX_PATH]; 137 | TCHAR svnBase[MAX_PATH]; 138 | 139 | _tcscpy_s(svnBase, _countof(svnBase), fullFilePath); 140 | ::PathRemoveFileSpec(svnBase); 141 | 142 | bool ret = LocateDirUp(TEXT(".svn"), svnBase, svnTop, _countof(svnTop)); 143 | 144 | if (ret) 145 | { 146 | ret = false; 147 | 148 | TCHAR dotSvnIdx[MAX_PATH]; 149 | 150 | ::PathCombine(dotSvnIdx, svnTop, TEXT(".svn")); 151 | ::PathCombine(svnBase, dotSvnIdx, TEXT("wc.db")); 152 | 153 | // is it SVN 1.7 or above? 154 | if (::PathFileExists(svnBase)) 155 | { 156 | if (!InitSQLite()) 157 | { 158 | ::MessageBox(nppData._nppHandle, TEXT("Failed to initialize SQLite - operation aborted."), 159 | PLUGIN_NAME, MB_OK); 160 | return false; 161 | } 162 | 163 | sqlite3* ppDb; 164 | 165 | if (sqlite3_open16(svnBase, &ppDb) == SQLITE_OK) 166 | { 167 | RelativePath(fullFilePath, svnTop, svnBase, _countof(svnBase)); 168 | 169 | TCHAR sqlQuery[MAX_PATH + 64]; 170 | _sntprintf_s(sqlQuery, _countof(sqlQuery), _TRUNCATE, 171 | TEXT("SELECT checksum FROM nodes_current WHERE local_relpath='%s';"), svnBase); 172 | 173 | sqlite3_stmt* pStmt; 174 | 175 | if (sqlite3_prepare16_v2(ppDb, sqlQuery, -1, &pStmt, NULL) == SQLITE_OK) 176 | { 177 | if (sqlite3_step(pStmt) == SQLITE_ROW) 178 | { 179 | const TCHAR* checksum = (const TCHAR*)sqlite3_column_text16(pStmt, 0); 180 | 181 | if (checksum[0] != 0) 182 | { 183 | TCHAR idx[128]; 184 | 185 | _tcsncpy_s(idx, _countof(idx), checksum + 6, 2); 186 | 187 | ::PathCombine(svnBase, dotSvnIdx, TEXT("pristine")); 188 | ::PathCombine(dotSvnIdx, svnBase, idx); 189 | 190 | _tcscpy_s(idx, _countof(idx), checksum + 6); 191 | 192 | ::PathCombine(svnBase, dotSvnIdx, idx); 193 | _tcscat_s(svnBase, _countof(svnBase), TEXT(".svn-base")); 194 | 195 | if (PathFileExists(svnBase)) 196 | { 197 | _tcscpy_s(svnFile, svnFileSize, svnBase); 198 | ret = true; 199 | } 200 | } 201 | } 202 | 203 | sqlite3_finalize(pStmt); 204 | } 205 | 206 | sqlite3_close(ppDb); 207 | } 208 | } 209 | else 210 | { 211 | ::PathCombine(svnTop, dotSvnIdx, TEXT("text-base")); 212 | 213 | const TCHAR* file = ::PathFindFileName(fullFilePath); 214 | 215 | ::PathCombine(svnBase, svnTop, file); 216 | _tcscat_s(svnBase, _countof(svnBase), TEXT(".svn-base")); 217 | 218 | // Is it an old SVN version? 219 | if (::PathFileExists(svnBase)) 220 | { 221 | _tcscpy_s(svnFile, svnFileSize, svnBase); 222 | ret = true; 223 | } 224 | } 225 | } 226 | 227 | if (!ret) 228 | ::MessageBox(nppData._nppHandle, TEXT("No SVN data found."), PLUGIN_NAME, MB_OK); 229 | 230 | return ret; 231 | } 232 | 233 | 234 | std::vector GetGitFileContent(const TCHAR* fullFilePath) 235 | { 236 | std::vector gitFileContent; 237 | 238 | std::unique_ptr& gitLib = LibGit::load(); 239 | if (!gitLib) 240 | { 241 | ::MessageBox(nppData._nppHandle, TEXT("Failed to initialize LibGit2 - operation aborted."), 242 | PLUGIN_NAME, MB_OK); 243 | return gitFileContent; 244 | } 245 | 246 | git_repository* repo = NULL; 247 | 248 | char ansiGitFilePath[MAX_PATH]; 249 | 250 | { 251 | char ansiPath[MAX_PATH * 2]; 252 | 253 | TCharToChar(fullFilePath, ansiPath, sizeof(ansiPath)); 254 | ::PathRemoveFileSpecA(ansiPath); 255 | 256 | if (!gitLib->repository_open_ext(&repo, ansiPath, 0, NULL)) 257 | { 258 | const char* ansiGitDir = gitLib->repository_workdir(repo); 259 | 260 | //reinit with fullFilePath after modification by PathRemoveFileSpecA(), needed to get the relative path 261 | TCharToChar(fullFilePath, ansiPath, sizeof(ansiPath)); 262 | 263 | RelativePath(ansiPath, ansiGitDir, ansiGitFilePath, sizeof(ansiGitFilePath)); 264 | } 265 | } 266 | 267 | if (repo) 268 | { 269 | git_index* index; 270 | 271 | if (!gitLib->repository_index(&index, repo)) 272 | { 273 | const git_index_entry* e = gitLib->index_get_bypath(index, ansiGitFilePath, 0); 274 | 275 | if (e) 276 | { 277 | git_blob* blob; 278 | 279 | if (!gitLib->blob_lookup(&blob, repo, &e->id)) 280 | { 281 | git_buf gitBuf = { 0 }; 282 | 283 | if (!gitLib->blob_filtered_content(&gitBuf, blob, ansiGitFilePath, 1)) 284 | { 285 | gitFileContent.resize(gitBuf.size + 1, 0); 286 | std::memcpy(gitFileContent.data(), gitBuf.ptr, gitBuf.size); 287 | 288 | gitLib->buf_free(&gitBuf); 289 | } 290 | 291 | gitLib->blob_free(blob); 292 | } 293 | } 294 | 295 | gitLib->index_free(index); 296 | } 297 | 298 | gitLib->repository_free(repo); 299 | } 300 | 301 | if (gitFileContent.empty()) 302 | ::MessageBox(nppData._nppHandle, TEXT("No Git data found."), PLUGIN_NAME, MB_OK); 303 | 304 | return gitFileContent; 305 | } 306 | -------------------------------------------------------------------------------- /src/LibHelpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C)2013 Jean-Sebastien Leroy (jean.sebastien.leroy@gmail.com) 4 | * Copyright (C)2017-2022 Pavel Nedev (pg.nedev@gmail.com) 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | bool isSQLlibFound(); 27 | bool isGITlibFound(); 28 | 29 | bool GetSvnFile(const TCHAR* fullFilePath, TCHAR* svnFile, unsigned svnFileSize); 30 | std::vector GetGitFileContent(const TCHAR* fullFilePath); 31 | -------------------------------------------------------------------------------- /src/NavDlg/NavDialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C)2017-2022 Pavel Nedev (pg.nedev@gmail.com) 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "Compare.h" 23 | #include "DockingFeature/Window.h" 24 | #include "DockingFeature/DockingDlgInterface.h" 25 | 26 | #include 27 | #include 28 | 29 | 30 | class NavDialog : public DockingDlgInterface 31 | { 32 | public: 33 | NavDialog(); 34 | ~NavDialog(); 35 | 36 | NavDialog(const NavDialog&) = delete; 37 | NavDialog& operator=(const NavDialog&) = delete; 38 | 39 | void init(HINSTANCE hInst); 40 | void destroy() {}; 41 | 42 | void Show(); 43 | void Hide(); 44 | 45 | bool SetColors(const ColorSettings& colors) 46 | { 47 | m_clr = colors; 48 | 49 | if (isVisible()) 50 | { 51 | Show(); 52 | return true; 53 | } 54 | 55 | return false; 56 | } 57 | 58 | void Update(); 59 | 60 | protected: 61 | virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); 62 | 63 | private: 64 | static const int cSpace; 65 | static const int cScrollerWidth; 66 | 67 | /** 68 | * \struct 69 | * \brief 70 | */ 71 | struct NavView 72 | { 73 | NavView() : m_view(0), m_hViewDC(NULL), m_hSelDC(NULL), m_hViewBMP(NULL), m_hSelBMP(NULL) {} 74 | 75 | ~NavView() 76 | { 77 | reset(); 78 | } 79 | 80 | void init(HDC hDC); 81 | void reset(); 82 | void paint(HDC hDC, int xPos, int yPos, int width, int height, int heightTotal, 83 | int hScale, int hOffset, bool shrinkLeftSideOfEmptyArea, int backColor); 84 | 85 | void updateFirstVisible() 86 | { 87 | m_firstVisible = CallScintilla(m_view, SCI_GETFIRSTVISIBLELINE, 0, 0); 88 | } 89 | 90 | int maxBmpLines() const 91 | { 92 | return static_cast(m_lineMap.empty() ? m_lines : m_lineMap.size()); 93 | } 94 | 95 | intptr_t bmpToDocLine(int bmpLine) const 96 | { 97 | if (bmpLine < 0) 98 | return 0; 99 | else if (m_lineMap.empty()) 100 | return bmpLine; 101 | else if (bmpLine < static_cast(m_lineMap.size())) 102 | return m_lineMap[bmpLine]; 103 | 104 | return m_lineMap.back(); 105 | } 106 | 107 | int docToBmpLine(intptr_t docLine) const; 108 | 109 | int m_view; 110 | 111 | HDC m_hViewDC; 112 | HDC m_hSelDC; 113 | 114 | HBITMAP m_hViewBMP; 115 | HBITMAP m_hSelBMP; 116 | 117 | intptr_t m_firstVisible; 118 | intptr_t m_lines; 119 | 120 | std::vector m_lineMap; 121 | }; 122 | 123 | void doDialog(); 124 | 125 | void createBitmaps(); 126 | void showScroller(RECT& r); 127 | 128 | void setScalingFactor(); 129 | 130 | void setPos(int x, int y); 131 | void onMouseWheel(int rolls); 132 | int updateScroll(); 133 | void onPaint(); 134 | void adjustScroll(int offset); 135 | 136 | tTbData _data; 137 | 138 | ColorSettings m_clr; 139 | 140 | HINSTANCE m_hInst; 141 | 142 | HWND m_hScroll; 143 | 144 | HBRUSH m_hBackBrush; 145 | HBRUSH m_hScrollerBackBrush; 146 | 147 | bool m_mouseOver; 148 | 149 | int m_navViewWidth1; 150 | int m_navViewWidth2; 151 | int m_navHeight; 152 | int m_navHeightTotal; 153 | 154 | int m_pixelsPerLine; 155 | int m_maxBmpLines; 156 | 157 | NavView m_view[2]; 158 | NavView* m_syncView; 159 | }; 160 | -------------------------------------------------------------------------------- /src/NppAPI/DockingFeature/Docking.h: -------------------------------------------------------------------------------- 1 | // This file is part of Notepad++ project 2 | // Copyright (C)2024 Don HO 3 | 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // at your option any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | 18 | #pragma once 19 | 20 | #include 21 | 22 | // ATTENTION : It's a part of interface header, so don't include the others header here 23 | 24 | // styles for containers 25 | #define CAPTION_TOP TRUE 26 | #define CAPTION_BOTTOM FALSE 27 | 28 | // defines for docking manager 29 | #define CONT_LEFT 0 30 | #define CONT_RIGHT 1 31 | #define CONT_TOP 2 32 | #define CONT_BOTTOM 3 33 | #define DOCKCONT_MAX 4 34 | 35 | // mask params for plugins of internal dialogs 36 | #define DWS_ICONTAB 0x00000001 // Icon for tabs are available 37 | #define DWS_ICONBAR 0x00000002 // Icon for icon bar are available (currently not supported) 38 | #define DWS_ADDINFO 0x00000004 // Additional information are in use 39 | #define DWS_USEOWNDARKMODE 0x00000008 // Use plugin's own dark mode 40 | #define DWS_PARAMSALL (DWS_ICONTAB|DWS_ICONBAR|DWS_ADDINFO) 41 | 42 | // default docking values for first call of plugin 43 | #define DWS_DF_CONT_LEFT (CONT_LEFT << 28) // default docking on left 44 | #define DWS_DF_CONT_RIGHT (CONT_RIGHT << 28) // default docking on right 45 | #define DWS_DF_CONT_TOP (CONT_TOP << 28) // default docking on top 46 | #define DWS_DF_CONT_BOTTOM (CONT_BOTTOM << 28) // default docking on bottom 47 | #define DWS_DF_FLOATING 0x80000000 // default state is floating 48 | 49 | 50 | struct tTbData { 51 | HWND hClient = nullptr; // client Window Handle 52 | const wchar_t* pszName = nullptr; // name of plugin (shown in window) 53 | int dlgID = 0; // a funcItem provides the function pointer to start a dialog. Please parse here these ID 54 | 55 | // user modifications 56 | UINT uMask = 0; // mask params: look to above defines 57 | HICON hIconTab = nullptr; // icon for tabs 58 | const wchar_t* pszAddInfo = nullptr; // for plugin to display additional informations 59 | 60 | // internal data, do not use !!! 61 | RECT rcFloat = {}; // floating position 62 | int iPrevCont = 0; // stores the privious container (toggling between float and dock) 63 | const wchar_t* pszModuleName = nullptr; // it's the plugin file name. It's used to identify the plugin 64 | }; 65 | 66 | 67 | struct tDockMgr { 68 | HWND hWnd = nullptr; // the docking manager wnd 69 | RECT rcRegion[DOCKCONT_MAX] = {{}}; // position of docked dialogs 70 | }; 71 | 72 | 73 | #define HIT_TEST_THICKNESS 20 74 | #define SPLITTER_WIDTH 4 75 | 76 | -------------------------------------------------------------------------------- /src/NppAPI/DockingFeature/DockingDlgInterface.h: -------------------------------------------------------------------------------- 1 | // This file is part of Notepad++ project 2 | // Copyright (C)2006 Jens Lorenz 3 | 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // at your option any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | 18 | #pragma once 19 | 20 | #include "dockingResource.h" 21 | #include "Docking.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include "StaticDialog.h" 27 | 28 | 29 | 30 | class DockingDlgInterface : public StaticDialog 31 | { 32 | public: 33 | DockingDlgInterface() = default; 34 | explicit DockingDlgInterface(int dlgID): _dlgID(dlgID) {} 35 | 36 | void init(HINSTANCE hInst, HWND parent) override { 37 | StaticDialog::init(hInst, parent); 38 | wchar_t temp[MAX_PATH]; 39 | ::GetModuleFileName(reinterpret_cast(hInst), temp, MAX_PATH); 40 | _moduleName = ::PathFindFileName(temp); 41 | } 42 | 43 | void create(tTbData* data, bool isRTL = false) { 44 | assert(data != nullptr); 45 | StaticDialog::create(_dlgID, isRTL); 46 | wchar_t temp[MAX_PATH]; 47 | ::GetWindowText(_hSelf, temp, MAX_PATH); 48 | _pluginName = temp; 49 | 50 | // user information 51 | data->hClient = _hSelf; 52 | data->pszName = _pluginName.c_str(); 53 | 54 | // supported features by plugin 55 | data->uMask = 0; 56 | 57 | // additional info 58 | data->pszAddInfo = NULL; 59 | } 60 | 61 | virtual void updateDockingDlg() { 62 | ::SendMessage(_hParent, NPPM_DMMUPDATEDISPINFO, 0, reinterpret_cast(_hSelf)); 63 | } 64 | 65 | virtual void setBackgroundColor(COLORREF) {} 66 | virtual void setForegroundColor(COLORREF) {} 67 | 68 | void display(bool toShow = true) const override { 69 | ::SendMessage(_hParent, toShow ? NPPM_DMMSHOW : NPPM_DMMHIDE, 0, reinterpret_cast(_hSelf)); 70 | } 71 | 72 | bool isClosed() const { 73 | return _isClosed; 74 | } 75 | 76 | void setClosed(bool toClose) { 77 | _isClosed = toClose; 78 | } 79 | 80 | const wchar_t * getPluginFileName() const { 81 | return _moduleName.c_str(); 82 | } 83 | 84 | protected : 85 | int _dlgID = -1; 86 | bool _isFloating = true; 87 | int _iDockedPos = 0; 88 | std::wstring _moduleName; 89 | std::wstring _pluginName; 90 | bool _isClosed = false; 91 | 92 | intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) override { 93 | switch (message) 94 | { 95 | // case WM_ERASEBKGND: 96 | // { 97 | // if (!NppDarkMode::isEnabled()) 98 | // { 99 | // break; 100 | // } 101 | 102 | // RECT rc = {}; 103 | // getClientRect(rc); 104 | // ::FillRect(reinterpret_cast(wParam), &rc, NppDarkMode::getDarkerBackgroundBrush()); 105 | // return TRUE; 106 | // } 107 | case WM_NOTIFY: 108 | { 109 | LPNMHDR pnmh = reinterpret_cast(lParam); 110 | 111 | if (pnmh->hwndFrom == _hParent) 112 | { 113 | switch (LOWORD(pnmh->code)) 114 | { 115 | case DMN_CLOSE: 116 | { 117 | break; 118 | } 119 | case DMN_FLOAT: 120 | { 121 | _isFloating = true; 122 | break; 123 | } 124 | case DMN_DOCK: 125 | { 126 | _iDockedPos = HIWORD(pnmh->code); 127 | _isFloating = false; 128 | break; 129 | } 130 | default: 131 | break; 132 | } 133 | } 134 | break; 135 | } 136 | default: 137 | break; 138 | } 139 | return FALSE; 140 | }; 141 | }; 142 | -------------------------------------------------------------------------------- /src/NppAPI/DockingFeature/StaticDialog.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Notepad++ project 2 | // Copyright (C)2024 Don HO 3 | 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // at your option any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include 18 | #include 19 | #include 20 | #include "StaticDialog.h" 21 | 22 | StaticDialog::~StaticDialog() 23 | { 24 | if (isCreated()) 25 | { 26 | // Prevent run_dlgProc from doing anything, since its virtual 27 | ::SetWindowLongPtr(_hSelf, GWLP_USERDATA, 0); 28 | destroy(); 29 | } 30 | } 31 | 32 | void StaticDialog::destroy() 33 | { 34 | ::SendMessage(_hParent, NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, reinterpret_cast(_hSelf)); 35 | ::DestroyWindow(_hSelf); 36 | } 37 | 38 | void StaticDialog::getMappedChildRect(HWND hChild, RECT& rcChild) const 39 | { 40 | ::GetClientRect(hChild, &rcChild); 41 | ::MapWindowPoints(hChild, _hSelf, reinterpret_cast(&rcChild), 2); 42 | } 43 | 44 | void StaticDialog::getMappedChildRect(int idChild, RECT& rcChild) const 45 | { 46 | const HWND hChild = ::GetDlgItem(_hSelf, idChild); 47 | getMappedChildRect(hChild, rcChild); 48 | } 49 | 50 | void StaticDialog::redrawDlgItem(const int nIDDlgItem, bool forceUpdate) const 51 | { 52 | RECT rcDlgItem{}; 53 | const HWND hDlgItem = ::GetDlgItem(_hSelf, nIDDlgItem); 54 | getMappedChildRect(hDlgItem, rcDlgItem); 55 | ::InvalidateRect(_hSelf, &rcDlgItem, TRUE); 56 | 57 | if (forceUpdate) 58 | ::UpdateWindow(hDlgItem); 59 | } 60 | 61 | POINT StaticDialog::getTopPoint(HWND hwnd, bool isLeft) const 62 | { 63 | RECT rc{}; 64 | ::GetWindowRect(hwnd, &rc); 65 | 66 | POINT p{}; 67 | if (isLeft) 68 | p.x = rc.left; 69 | else 70 | p.x = rc.right; 71 | 72 | p.y = rc.top; 73 | ::ScreenToClient(_hSelf, &p); 74 | return p; 75 | } 76 | 77 | void StaticDialog::goToCenter(UINT swpFlags) 78 | { 79 | RECT rc{}; 80 | ::GetClientRect(_hParent, &rc); 81 | if ((rc.left == rc.right) || (rc.top == rc.bottom)) 82 | swpFlags |= SWP_NOSIZE; // sizing has no sense here 83 | 84 | POINT center{}; 85 | center.x = rc.left + (rc.right - rc.left)/2; 86 | center.y = rc.top + (rc.bottom - rc.top)/2; 87 | ::ClientToScreen(_hParent, ¢er); 88 | if ((center.x == -32000) && (center.y == -32000)) // https://devblogs.microsoft.com/oldnewthing/20041028-00/?p=37453 89 | swpFlags |= SWP_NOMOVE; // moving has no sense here (owner wnd is minimized) 90 | 91 | int x = center.x - (_rc.right - _rc.left)/2; 92 | int y = center.y - (_rc.bottom - _rc.top)/2; 93 | 94 | ::SetWindowPos(_hSelf, HWND_TOP, x, y, _rc.right - _rc.left, _rc.bottom - _rc.top, swpFlags); 95 | if (((swpFlags & SWP_NOMOVE) != SWP_NOMOVE) && ((swpFlags & SWP_SHOWWINDOW) == SWP_SHOWWINDOW)) 96 | ::SendMessageW(_hSelf, DM_REPOSITION, 0, 0); 97 | } 98 | 99 | void StaticDialog::display(bool toShow, bool enhancedPositioningCheckWhenShowing) const 100 | { 101 | if (toShow) 102 | { 103 | if (enhancedPositioningCheckWhenShowing) 104 | { 105 | RECT testPositionRc{}, candidateRc{}; 106 | 107 | getWindowRect(testPositionRc); 108 | 109 | candidateRc = getViewablePositionRect(testPositionRc); 110 | 111 | if ((testPositionRc.left != candidateRc.left) || (testPositionRc.top != candidateRc.top)) 112 | { 113 | ::MoveWindow(_hSelf, candidateRc.left, candidateRc.top, 114 | candidateRc.right - candidateRc.left, candidateRc.bottom - candidateRc.top, TRUE); 115 | } 116 | } 117 | else 118 | { 119 | // If the user has switched from a dual monitor to a single monitor since we last 120 | // displayed the dialog, then ensure that it's still visible on the single monitor. 121 | RECT workAreaRect{}; 122 | RECT rc{}; 123 | ::SystemParametersInfo(SPI_GETWORKAREA, 0, &workAreaRect, 0); 124 | ::GetWindowRect(_hSelf, &rc); 125 | int newLeft = rc.left; 126 | int newTop = rc.top; 127 | int margin = ::GetSystemMetrics(SM_CYSMCAPTION); 128 | 129 | if (newLeft > ::GetSystemMetrics(SM_CXVIRTUALSCREEN) - margin) 130 | newLeft -= rc.right - workAreaRect.right; 131 | if (newLeft + (rc.right - rc.left) < ::GetSystemMetrics(SM_XVIRTUALSCREEN) + margin) 132 | newLeft = workAreaRect.left; 133 | if (newTop > ::GetSystemMetrics(SM_CYVIRTUALSCREEN) - margin) 134 | newTop -= rc.bottom - workAreaRect.bottom; 135 | if (newTop + (rc.bottom - rc.top) < ::GetSystemMetrics(SM_YVIRTUALSCREEN) + margin) 136 | newTop = workAreaRect.top; 137 | 138 | if ((newLeft != rc.left) || (newTop != rc.top)) // then the virtual screen size has shrunk 139 | ::SetWindowPos(_hSelf, nullptr, newLeft, newTop, 0, 0, SWP_NOSIZE | SWP_NOZORDER); 140 | else 141 | ::SendMessageW(_hSelf, DM_REPOSITION, 0, 0); 142 | } 143 | } 144 | 145 | Window::display(toShow); 146 | } 147 | 148 | RECT StaticDialog::getViewablePositionRect(RECT testPositionRc) const 149 | { 150 | HMONITOR hMon = ::MonitorFromRect(&testPositionRc, MONITOR_DEFAULTTONULL); 151 | 152 | MONITORINFO mi{}; 153 | mi.cbSize = sizeof(MONITORINFO); 154 | 155 | bool rectPosViewableWithoutChange = false; 156 | 157 | if (hMon != NULL) 158 | { 159 | // rect would be at least partially visible on a monitor 160 | 161 | ::GetMonitorInfo(hMon, &mi); 162 | 163 | int margin = ::GetSystemMetrics(SM_CYBORDER) + ::GetSystemMetrics(SM_CYSIZEFRAME) + ::GetSystemMetrics(SM_CYCAPTION); 164 | 165 | // require that the title bar of the window be in a viewable place so the user can see it to grab it with the mouse 166 | if ((testPositionRc.top >= mi.rcWork.top) && (testPositionRc.top + margin <= mi.rcWork.bottom) && 167 | // require that some reasonable amount of width of the title bar be in the viewable area: 168 | (testPositionRc.right - (margin * 2) > mi.rcWork.left) && (testPositionRc.left + (margin * 2) < mi.rcWork.right)) 169 | { 170 | rectPosViewableWithoutChange = true; 171 | } 172 | } 173 | else 174 | { 175 | // rect would not have been visible on a monitor; get info about the nearest monitor to it 176 | 177 | hMon = ::MonitorFromRect(&testPositionRc, MONITOR_DEFAULTTONEAREST); 178 | 179 | ::GetMonitorInfo(hMon, &mi); 180 | } 181 | 182 | RECT returnRc = testPositionRc; 183 | 184 | if (!rectPosViewableWithoutChange) 185 | { 186 | // reposition rect so that it would be viewable on current/nearest monitor, centering if reasonable 187 | 188 | LONG testRectWidth = testPositionRc.right - testPositionRc.left; 189 | LONG testRectHeight = testPositionRc.bottom - testPositionRc.top; 190 | LONG monWidth = mi.rcWork.right - mi.rcWork.left; 191 | LONG monHeight = mi.rcWork.bottom - mi.rcWork.top; 192 | 193 | returnRc.left = mi.rcWork.left; 194 | if (testRectWidth < monWidth) returnRc.left += (monWidth - testRectWidth) / 2; 195 | returnRc.right = returnRc.left + testRectWidth; 196 | 197 | returnRc.top = mi.rcWork.top; 198 | if (testRectHeight < monHeight) returnRc.top += (monHeight - testRectHeight) / 2; 199 | returnRc.bottom = returnRc.top + testRectHeight; 200 | } 201 | 202 | return returnRc; 203 | } 204 | 205 | HGLOBAL StaticDialog::makeRTLResource(int dialogID, DLGTEMPLATE **ppMyDlgTemplate) 206 | { 207 | // Get Dlg Template resource 208 | HRSRC hDialogRC = ::FindResource(_hInst, MAKEINTRESOURCE(dialogID), RT_DIALOG); 209 | if (!hDialogRC) 210 | return NULL; 211 | 212 | HGLOBAL hDlgTemplate = ::LoadResource(_hInst, hDialogRC); 213 | if (!hDlgTemplate) 214 | return NULL; 215 | 216 | const DLGTEMPLATE *pDlgTemplate = static_cast(::LockResource(hDlgTemplate)); 217 | if (!pDlgTemplate) 218 | return NULL; 219 | 220 | // Duplicate Dlg Template resource 221 | unsigned long sizeDlg = ::SizeofResource(_hInst, hDialogRC); 222 | HGLOBAL hMyDlgTemplate = ::GlobalAlloc(GPTR, sizeDlg); 223 | if (!hMyDlgTemplate) return nullptr; 224 | 225 | *ppMyDlgTemplate = static_cast(::GlobalLock(hMyDlgTemplate)); 226 | if (!*ppMyDlgTemplate) return nullptr; 227 | 228 | ::memcpy(*ppMyDlgTemplate, pDlgTemplate, sizeDlg); 229 | 230 | DLGTEMPLATEEX* pMyDlgTemplateEx = reinterpret_cast(*ppMyDlgTemplate); 231 | if (!pMyDlgTemplateEx) return nullptr; 232 | 233 | if (pMyDlgTemplateEx->signature == 0xFFFF) 234 | pMyDlgTemplateEx->exStyle |= WS_EX_LAYOUTRTL; 235 | else 236 | (*ppMyDlgTemplate)->dwExtendedStyle |= WS_EX_LAYOUTRTL; 237 | 238 | return hMyDlgTemplate; 239 | } 240 | 241 | std::wstring GetLastErrorAsString(DWORD errorCode) 242 | { 243 | std::wstring errorMsg(_T("")); 244 | // Get the error message, if any. 245 | // If both error codes (passed error n GetLastError) are 0, then return empty 246 | if (errorCode == 0) 247 | errorCode = GetLastError(); 248 | if (errorCode == 0) 249 | return errorMsg; //No error message has been recorded 250 | 251 | LPWSTR messageBuffer = nullptr; 252 | FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 253 | nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, nullptr); 254 | 255 | errorMsg += messageBuffer; 256 | 257 | //Free the buffer. 258 | LocalFree(messageBuffer); 259 | 260 | return errorMsg; 261 | } 262 | 263 | void StaticDialog::create(int dialogID, bool isRTL, bool msgDestParent) 264 | { 265 | if (isRTL) 266 | { 267 | DLGTEMPLATE *pMyDlgTemplate = NULL; 268 | HGLOBAL hMyDlgTemplate = makeRTLResource(dialogID, &pMyDlgTemplate); 269 | _hSelf = ::CreateDialogIndirectParam(_hInst, pMyDlgTemplate, _hParent, dlgProc, reinterpret_cast(this)); 270 | ::GlobalFree(hMyDlgTemplate); 271 | } 272 | else 273 | _hSelf = ::CreateDialogParam(_hInst, MAKEINTRESOURCE(dialogID), _hParent, dlgProc, reinterpret_cast(this)); 274 | 275 | if (!_hSelf) 276 | { 277 | std::wstring errMsg = L"CreateDialogParam() return NULL.\rGetLastError(): "; 278 | errMsg += GetLastErrorAsString(0); 279 | ::MessageBox(NULL, errMsg.c_str(), L"In StaticDialog::create()", MB_OK); 280 | return; 281 | } 282 | 283 | // if the destination of message NPPM_MODELESSDIALOG is not its parent, then it's the grand-parent 284 | ::SendMessage(msgDestParent ? _hParent : (::GetParent(_hParent)), NPPM_MODELESSDIALOG, MODELESSDIALOGADD, reinterpret_cast(_hSelf)); 285 | } 286 | 287 | intptr_t CALLBACK StaticDialog::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 288 | { 289 | switch (message) 290 | { 291 | case WM_INITDIALOG: 292 | { 293 | StaticDialog *pStaticDlg = reinterpret_cast(lParam); 294 | pStaticDlg->_hSelf = hwnd; 295 | ::SetWindowLongPtr(hwnd, GWLP_USERDATA, static_cast(lParam)); 296 | ::GetWindowRect(hwnd, &(pStaticDlg->_rc)); 297 | pStaticDlg->run_dlgProc(message, wParam, lParam); 298 | 299 | return TRUE; 300 | } 301 | 302 | default: 303 | { 304 | StaticDialog *pStaticDlg = reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); 305 | if (!pStaticDlg) 306 | return FALSE; 307 | return pStaticDlg->run_dlgProc(message, wParam, lParam); 308 | } 309 | } 310 | } 311 | -------------------------------------------------------------------------------- /src/NppAPI/DockingFeature/StaticDialog.h: -------------------------------------------------------------------------------- 1 | // This file is part of Notepad++ project 2 | // Copyright (C)2024 Don HO 3 | 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // at your option any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | #include "../Notepad_plus_msgs.h" 19 | #include "Window.h" 20 | 21 | typedef HRESULT (WINAPI * ETDTProc) (HWND, DWORD); 22 | 23 | enum class PosAlign { left, right, top, bottom }; 24 | 25 | struct DLGTEMPLATEEX 26 | { 27 | WORD dlgVer = 0; 28 | WORD signature = 0; 29 | DWORD helpID = 0; 30 | DWORD exStyle = 0; 31 | DWORD style = 0; 32 | WORD cDlgItems = 0; 33 | short x = 0; 34 | short y = 0; 35 | short cx = 0; 36 | short cy = 0; 37 | // The structure has more fields but are variable length 38 | }; 39 | 40 | class StaticDialog : public Window 41 | { 42 | public : 43 | virtual ~StaticDialog(); 44 | 45 | virtual void create(int dialogID, bool isRTL = false, bool msgDestParent = true); 46 | 47 | virtual bool isCreated() const { 48 | return (_hSelf != nullptr); 49 | } 50 | 51 | void getMappedChildRect(HWND hChild, RECT& rcChild) const; 52 | void getMappedChildRect(int idChild, RECT& rcChild) const; 53 | void redrawDlgItem(const int nIDDlgItem, bool forceUpdate = false) const; 54 | 55 | void goToCenter(UINT swpFlags = SWP_SHOWWINDOW); 56 | 57 | void display(bool toShow = true, bool enhancedPositioningCheckWhenShowing = false) const; 58 | 59 | RECT getViewablePositionRect(RECT testRc) const; 60 | 61 | POINT getTopPoint(HWND hwnd, bool isLeft = true) const; 62 | 63 | bool isCheckedOrNot(int checkControlID) const 64 | { 65 | return (BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, checkControlID), BM_GETCHECK, 0, 0)); 66 | } 67 | 68 | void setChecked(int checkControlID, bool checkOrNot = true) const 69 | { 70 | ::SendDlgItemMessage(_hSelf, checkControlID, BM_SETCHECK, checkOrNot ? BST_CHECKED : BST_UNCHECKED, 0); 71 | } 72 | 73 | void destroy() override; 74 | 75 | protected: 76 | RECT _rc{}; 77 | 78 | static intptr_t CALLBACK dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 79 | virtual intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) = 0; 80 | 81 | HGLOBAL makeRTLResource(int dialogID, DLGTEMPLATE **ppMyDlgTemplate); 82 | }; 83 | -------------------------------------------------------------------------------- /src/NppAPI/DockingFeature/Window.h: -------------------------------------------------------------------------------- 1 | // This file is part of Notepad++ project 2 | // Copyright (C)2024 Don HO 3 | 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // at your option any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | 18 | #pragma once 19 | #include 20 | 21 | class Window 22 | { 23 | public: 24 | //! \name Constructors & Destructor 25 | //@{ 26 | Window() = default; 27 | Window(const Window&) = delete; 28 | virtual ~Window() = default; 29 | //@} 30 | 31 | 32 | virtual void init(HINSTANCE hInst, HWND parent) { 33 | _hInst = hInst; 34 | _hParent = parent; 35 | } 36 | 37 | virtual void destroy() = 0; 38 | 39 | virtual void display(bool toShow = true) const { 40 | ::ShowWindow(_hSelf, toShow ? SW_SHOW : SW_HIDE); 41 | } 42 | 43 | 44 | virtual void reSizeTo(RECT & rc) { // should NEVER be const !!! 45 | ::MoveWindow(_hSelf, rc.left, rc.top, rc.right, rc.bottom, TRUE); 46 | redraw(); 47 | } 48 | 49 | 50 | virtual void reSizeToWH(RECT& rc) { // should NEVER be const !!! 51 | ::MoveWindow(_hSelf, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); 52 | redraw(); 53 | } 54 | 55 | 56 | virtual void redraw(bool forceUpdate = false) const { 57 | ::InvalidateRect(_hSelf, nullptr, TRUE); 58 | if (forceUpdate) 59 | ::UpdateWindow(_hSelf); 60 | } 61 | 62 | 63 | virtual void getClientRect(RECT & rc) const { 64 | ::GetClientRect(_hSelf, &rc); 65 | } 66 | 67 | virtual void getWindowRect(RECT & rc) const { 68 | ::GetWindowRect(_hSelf, &rc); 69 | } 70 | 71 | virtual int getWidth() const { 72 | RECT rc; 73 | ::GetClientRect(_hSelf, &rc); 74 | return (rc.right - rc.left); 75 | } 76 | 77 | virtual int getHeight() const { 78 | RECT rc; 79 | ::GetClientRect(_hSelf, &rc); 80 | if (::IsWindowVisible(_hSelf) == TRUE) 81 | return (rc.bottom - rc.top); 82 | return 0; 83 | } 84 | 85 | virtual bool isVisible() const 86 | { 87 | return (::IsWindowVisible(_hSelf)?true:false); 88 | } 89 | 90 | HWND getHSelf() const { 91 | return _hSelf; 92 | } 93 | 94 | HWND getHParent() const { 95 | return _hParent; 96 | } 97 | 98 | void grabFocus() const { 99 | ::SetFocus(_hSelf); 100 | } 101 | 102 | HINSTANCE getHinst() const { 103 | return _hInst; 104 | } 105 | 106 | 107 | Window& operator = (const Window&) = delete; 108 | 109 | 110 | protected: 111 | HINSTANCE _hInst = NULL; 112 | HWND _hParent = NULL; 113 | HWND _hSelf = NULL; 114 | }; -------------------------------------------------------------------------------- /src/NppAPI/DockingFeature/dockingResource.h: -------------------------------------------------------------------------------- 1 | // This file is part of Notepad++ project 2 | // Copyright (C)2006 Jens Lorenz 3 | 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // at your option any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | 18 | #pragma once 19 | 20 | #define DM_NOFOCUSWHILECLICKINGCAPTION L"NOFOCUSWHILECLICKINGCAPTION" 21 | 22 | #define IDD_PLUGIN_DLG 103 23 | #define IDC_EDIT1 1000 24 | 25 | 26 | #define IDB_CLOSE_DOWN 137 27 | #define IDB_CLOSE_UP 138 28 | #define IDD_CONTAINER_DLG 139 29 | 30 | #define IDC_TAB_CONT 1027 31 | #define IDC_CLIENT_TAB 1028 32 | #define IDC_BTN_CAPTION 1050 33 | 34 | #define DMM_MSG 0x5000 35 | #define DMM_CLOSE (DMM_MSG + 1) 36 | #define DMM_DOCK (DMM_MSG + 2) 37 | #define DMM_FLOAT (DMM_MSG + 3) 38 | #define DMM_DOCKALL (DMM_MSG + 4) 39 | #define DMM_FLOATALL (DMM_MSG + 5) 40 | #define DMM_MOVE (DMM_MSG + 6) 41 | #define DMM_UPDATEDISPINFO (DMM_MSG + 7) 42 | //#define DMM_GETIMAGELIST (DMM_MSG + 8) 43 | //#define DMM_GETICONPOS (DMM_MSG + 9) 44 | #define DMM_DROPDATA (DMM_MSG + 10) 45 | #define DMM_MOVE_SPLITTER (DMM_MSG + 11) 46 | #define DMM_CANCEL_MOVE (DMM_MSG + 12) 47 | #define DMM_LBUTTONUP (DMM_MSG + 13) 48 | 49 | #define DMN_FIRST 1050 50 | #define DMN_CLOSE (DMN_FIRST + 1) 51 | //nmhdr.code = DWORD(DMN_CLOSE, 0)); 52 | //nmhdr.hwndFrom = hwndNpp; 53 | //nmhdr.idFrom = ctrlIdNpp; 54 | 55 | #define DMN_DOCK (DMN_FIRST + 2) 56 | #define DMN_FLOAT (DMN_FIRST + 3) 57 | //nmhdr.code = DWORD(DMN_XXX, int newContainer); 58 | //nmhdr.hwndFrom = hwndNpp; 59 | //nmhdr.idFrom = ctrlIdNpp; 60 | 61 | #define DMN_SWITCHIN (DMN_FIRST + 4) 62 | #define DMN_SWITCHOFF (DMN_FIRST + 5) 63 | #define DMN_FLOATDROPPED (DMN_FIRST + 6) 64 | //nmhdr.code = DWORD(DMN_XXX, 0); 65 | //nmhdr.hwndFrom = DockingCont::_hself; 66 | //nmhdr.idFrom = 0; 67 | 68 | -------------------------------------------------------------------------------- /src/NppAPI/NppInternalDefines.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C) 2017 Pavel Nedev (pg.nedev@gmail.com) 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | // WARNING: This file contains Notepad++ internal defines that are not part of its plugins API and are not intended 21 | // for use outside Notepad++ itself. This means that those might change in future Notepad++ versions without notice! 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | #define WM_TABSETSTYLE (WM_APP + 0x024) 28 | -------------------------------------------------------------------------------- /src/NppAPI/PluginInterface.h: -------------------------------------------------------------------------------- 1 | // This file is part of Notepad++ project 2 | // Copyright (C)2024 Don HO 3 | 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // at your option any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | 18 | 19 | // For more comprehensive information on plugin communication, please refer to the following resource: 20 | // https://npp-user-manual.org/docs/plugin-communication/ 21 | 22 | #pragma once 23 | 24 | #include "Scintilla.h" 25 | #include "Notepad_plus_msgs.h" 26 | 27 | 28 | typedef const TCHAR * (__cdecl * PFUNCGETNAME)(); 29 | 30 | struct NppData 31 | { 32 | HWND _nppHandle = nullptr; 33 | HWND _scintillaMainHandle = nullptr; 34 | HWND _scintillaSecondHandle = nullptr; 35 | }; 36 | 37 | typedef void (__cdecl * PFUNCSETINFO)(NppData); 38 | typedef void (__cdecl * PFUNCPLUGINCMD)(); 39 | typedef void (__cdecl * PBENOTIFIED)(SCNotification *); 40 | typedef LRESULT (__cdecl * PMESSAGEPROC)(UINT Message, WPARAM wParam, LPARAM lParam); 41 | 42 | 43 | struct ShortcutKey 44 | { 45 | bool _isCtrl = false; 46 | bool _isAlt = false; 47 | bool _isShift = false; 48 | UCHAR _key = 0; 49 | }; 50 | 51 | const int menuItemSize = 64; 52 | 53 | struct FuncItem 54 | { 55 | TCHAR _itemName[menuItemSize] = { '\0' }; 56 | PFUNCPLUGINCMD _pFunc = nullptr; 57 | int _cmdID = 0; 58 | bool _init2Check = false; 59 | ShortcutKey *_pShKey = nullptr; 60 | }; 61 | 62 | typedef FuncItem * (__cdecl * PFUNCGETFUNCSARRAY)(int *); 63 | 64 | // You should implement (or define an empty function body) those functions which are called by Notepad++ plugin manager 65 | extern "C" __declspec(dllexport) void setInfo(NppData); 66 | extern "C" __declspec(dllexport) const TCHAR * getName(); 67 | extern "C" __declspec(dllexport) FuncItem * getFuncsArray(int *); 68 | extern "C" __declspec(dllexport) void beNotified(SCNotification *); 69 | extern "C" __declspec(dllexport) LRESULT messageProc(UINT Message, WPARAM wParam, LPARAM lParam); 70 | 71 | // This API return always true now, since Notepad++ isn't compiled in ANSI mode anymore 72 | extern "C" __declspec(dllexport) BOOL isUnicode(); 73 | 74 | -------------------------------------------------------------------------------- /src/NppAPI/Sci_Position.h: -------------------------------------------------------------------------------- 1 | // Scintilla source code edit control 2 | /** @file Sci_Position.h 3 | ** Define the Sci_Position type used in Scintilla's external interfaces. 4 | ** These need to be available to clients written in C so are not in a C++ namespace. 5 | **/ 6 | // Copyright 2015 by Neil Hodgson 7 | // The License.txt file describes the conditions under which this software may be distributed. 8 | 9 | #ifndef SCI_POSITION_H 10 | #define SCI_POSITION_H 11 | 12 | #include 13 | 14 | // Basic signed type used throughout interface 15 | typedef ptrdiff_t Sci_Position; 16 | 17 | // Unsigned variant used for ILexer::Lex and ILexer::Fold 18 | typedef size_t Sci_PositionU; 19 | 20 | // For Sci_CharacterRange which is defined as long to be compatible with Win32 CHARRANGE 21 | typedef intptr_t Sci_PositionCR; 22 | 23 | #ifdef _WIN32 24 | #define SCI_METHOD __stdcall 25 | #else 26 | #define SCI_METHOD 27 | #endif 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/ProgressDlg/ProgressDlg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #pragma comment (lib, "comctl32") 19 | 20 | 21 | #include 22 | #include 23 | 24 | #include "Compare.h" 25 | #include "ProgressDlg.h" 26 | 27 | 28 | const TCHAR ProgressDlg::cClassName[] = TEXT("ComparePlusProgressClass"); 29 | const int ProgressDlg::cBackgroundColor = COLOR_3DFACE; 30 | const int ProgressDlg::cPBwidth = 600; 31 | const int ProgressDlg::cPBheight = 10; 32 | const int ProgressDlg::cBTNwidth = 80; 33 | const int ProgressDlg::cBTNheight = 25; 34 | 35 | 36 | // Different compare phases progress end positions 37 | const int ProgressDlg::cPhases[] = { 38 | 5, // Docs1 hashes 39 | 10, // Docs2 hashes 40 | 20, // Docs diff 41 | 90, // Blocks diff 42 | 100, // Results colorization and presentation 43 | }; 44 | 45 | 46 | progress_ptr ProgressDlg::Inst; 47 | 48 | 49 | progress_ptr& ProgressDlg::Open(const TCHAR* info) 50 | { 51 | if (Inst) 52 | return Inst; 53 | 54 | Inst.reset(new ProgressDlg); 55 | 56 | if (Inst) 57 | { 58 | if (Inst->create() == NULL) 59 | { 60 | Inst.reset(); 61 | } 62 | else 63 | { 64 | ::EnableWindow(nppData._nppHandle, FALSE); 65 | 66 | if (info) 67 | Inst->SetInfo(info); 68 | } 69 | } 70 | 71 | return Inst; 72 | } 73 | 74 | 75 | void ProgressDlg::Show() const 76 | { 77 | if (_hwnd) 78 | { 79 | if (_phase + 1 == _countof(cPhases)) 80 | { 81 | ::SendMessage(_hwnd, WM_CLOSE, 0, 0); 82 | } 83 | else 84 | { 85 | ::ShowWindow(_hwnd, SW_SHOWNORMAL); 86 | ::UpdateWindow(_hwnd); 87 | } 88 | 89 | ::KillTimer(_hwnd, 1); 90 | } 91 | } 92 | 93 | 94 | bool ProgressDlg::IsCancelled() const 95 | { 96 | return (::WaitForSingleObject(_hActiveState, 0) != WAIT_OBJECT_0); 97 | } 98 | 99 | 100 | unsigned ProgressDlg::NextPhase() 101 | { 102 | if (IsCancelled()) 103 | return 0; 104 | 105 | if (_phase + 1 < _countof(cPhases)) 106 | { 107 | _phasePosOffset = cPhases[_phase++]; 108 | _phaseRange = cPhases[_phase] - _phasePosOffset; 109 | _max = _phaseRange; 110 | _count = 0; 111 | setPos(_phasePosOffset); 112 | } 113 | else 114 | { 115 | setPos(cPhases[_countof(cPhases) - 1]); 116 | } 117 | 118 | return _phase + 1; 119 | } 120 | 121 | 122 | bool ProgressDlg::SetMaxCount(intptr_t max, unsigned phase) 123 | { 124 | if (IsCancelled()) 125 | return false; 126 | 127 | if (phase == 0 || phase - 1 == _phase) 128 | { 129 | _max = max; 130 | _count = 0; 131 | } 132 | 133 | return true; 134 | } 135 | 136 | 137 | bool ProgressDlg::SetCount(intptr_t cnt, unsigned phase) 138 | { 139 | if (IsCancelled()) 140 | return false; 141 | 142 | if ((phase == 0 || phase - 1 == _phase) && _count < cnt && cnt <= _max) 143 | { 144 | _count = cnt; 145 | update(); 146 | } 147 | 148 | return true; 149 | } 150 | 151 | 152 | bool ProgressDlg::Advance(intptr_t cnt, unsigned phase) 153 | { 154 | if (IsCancelled()) 155 | return false; 156 | 157 | if (phase == 0 || phase - 1 == _phase) 158 | { 159 | _count += cnt; 160 | update(); 161 | } 162 | 163 | return true; 164 | } 165 | 166 | 167 | ProgressDlg::ProgressDlg() : _hwnd(NULL), _hKeyHook(NULL), 168 | _phase(0), _phaseRange(cPhases[0]), _phasePosOffset(0), _max(cPhases[0]), _count(0), _pos(0) 169 | { 170 | ::GetModuleHandleEx( 171 | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 172 | GET_MODULE_HANDLE_EX_FLAG_PIN, cClassName, &_hInst); 173 | 174 | WNDCLASSEX wcex; 175 | 176 | ::SecureZeroMemory(&wcex, sizeof(wcex)); 177 | wcex.cbSize = sizeof(wcex); 178 | wcex.style = CS_HREDRAW | CS_VREDRAW; 179 | wcex.lpfnWndProc = wndProc; 180 | wcex.hInstance = _hInst; 181 | wcex.hCursor = ::LoadCursor(NULL, IDC_ARROW); 182 | wcex.hbrBackground = ::GetSysColorBrush(cBackgroundColor); 183 | wcex.lpszClassName = cClassName; 184 | 185 | ::RegisterClassEx(&wcex); 186 | 187 | INITCOMMONCONTROLSEX icex; 188 | 189 | ::SecureZeroMemory(&icex, sizeof(icex)); 190 | icex.dwSize = sizeof(icex); 191 | icex.dwICC = ICC_STANDARD_CLASSES | ICC_PROGRESS_CLASS; 192 | 193 | ::InitCommonControlsEx(&icex); 194 | } 195 | 196 | 197 | ProgressDlg::~ProgressDlg() 198 | { 199 | if (_hKeyHook) 200 | ::UnhookWindowsHookEx(_hKeyHook); 201 | 202 | destroy(); 203 | 204 | ::EnableWindow(nppData._nppHandle, TRUE); 205 | ::SetForegroundWindow(nppData._nppHandle); 206 | 207 | ::UnregisterClass(cClassName, _hInst); 208 | } 209 | 210 | 211 | HWND ProgressDlg::create() 212 | { 213 | // Create manually reset non-signaled event 214 | _hActiveState = ::CreateEvent(NULL, TRUE, FALSE, NULL); 215 | if (!_hActiveState) 216 | return NULL; 217 | 218 | for (HWND hwnd = nppData._nppHandle; hwnd; hwnd = ::GetParent(hwnd)) 219 | ::UpdateWindow(hwnd); 220 | 221 | _hThread = ::CreateThread(NULL, 0, threadFunc, this, 0, NULL); 222 | if (!_hThread) 223 | { 224 | ::CloseHandle(_hActiveState); 225 | return NULL; 226 | } 227 | 228 | // Wait for the progress window to be created 229 | ::WaitForSingleObject(_hActiveState, INFINITE); 230 | 231 | // On progress window create fail 232 | if (!_hwnd) 233 | { 234 | ::WaitForSingleObject(_hThread, INFINITE); 235 | ::CloseHandle(_hThread); 236 | ::CloseHandle(_hActiveState); 237 | } 238 | 239 | return _hwnd; 240 | } 241 | 242 | 243 | void ProgressDlg::cancel() 244 | { 245 | ::ResetEvent(_hActiveState); 246 | ::EnableWindow(_hBtn, FALSE); 247 | 248 | SetInfo(TEXT("Cancelling compare, please wait...")); 249 | } 250 | 251 | 252 | void ProgressDlg::destroy() 253 | { 254 | if (_hwnd) 255 | { 256 | ::KillTimer(_hwnd, 1); 257 | ::PostMessage(_hwnd, WM_CLOSE, 0, 0); 258 | _hwnd = NULL; 259 | 260 | ::WaitForSingleObject(_hThread, INFINITE); 261 | ::CloseHandle(_hThread); 262 | ::CloseHandle(_hActiveState); 263 | } 264 | } 265 | 266 | 267 | void ProgressDlg::update() 268 | { 269 | const unsigned newPos = static_cast(((_count * _phaseRange) / _max) + _phasePosOffset); 270 | 271 | if (newPos > _pos) 272 | { 273 | _pos = newPos; 274 | setPos(newPos); 275 | } 276 | } 277 | 278 | 279 | DWORD WINAPI ProgressDlg::threadFunc(LPVOID data) 280 | { 281 | ProgressDlg* pw = static_cast(data); 282 | return (DWORD)pw->thread(); 283 | } 284 | 285 | 286 | BOOL ProgressDlg::thread() 287 | { 288 | BOOL r = createProgressWindow(); 289 | ::SetEvent(_hActiveState); 290 | if (!r) 291 | return r; 292 | 293 | // Window message loop 294 | MSG msg; 295 | while ((r = ::GetMessage(&msg, NULL, 0, 0)) != 0 && r != -1) 296 | ::DispatchMessage(&msg); 297 | 298 | return r; 299 | } 300 | 301 | 302 | BOOL ProgressDlg::createProgressWindow() 303 | { 304 | _hwnd = ::CreateWindowEx( 305 | WS_EX_APPWINDOW | WS_EX_TOOLWINDOW | WS_EX_OVERLAPPEDWINDOW, 306 | cClassName, PLUGIN_NAME, WS_POPUP | WS_CAPTION, 307 | CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 308 | NULL, NULL, _hInst, (LPVOID)this); 309 | if (!_hwnd) 310 | return FALSE; 311 | 312 | int width = cPBwidth + 10; 313 | int height = cPBheight + cBTNheight + 35; 314 | RECT win = adjustSizeAndPos(width, height); 315 | ::MoveWindow(_hwnd, win.left, win.top, win.right - win.left, win.bottom - win.top, TRUE); 316 | 317 | ::GetClientRect(_hwnd, &win); 318 | width = win.right - win.left; 319 | height = win.bottom - win.top; 320 | 321 | _hPText = ::CreateWindowEx(0, TEXT("STATIC"), TEXT(""), 322 | WS_CHILD | WS_VISIBLE | BS_TEXT | SS_PATHELLIPSIS, 323 | 5, 5, width - 10, 20, _hwnd, NULL, _hInst, NULL); 324 | 325 | _hPBar = ::CreateWindowEx(0, PROGRESS_CLASS, TEXT("Progress Bar"), 326 | WS_CHILD | WS_VISIBLE | PBS_SMOOTH, 327 | 5, 25, width - 10, cPBheight, 328 | _hwnd, NULL, _hInst, NULL); 329 | ::SendMessage(_hPBar, PBM_SETRANGE, 0, MAKELPARAM(0, cPhases[_countof(cPhases) - 1])); 330 | 331 | _hBtn = ::CreateWindowEx(0, TEXT("BUTTON"), TEXT("Cancel"), 332 | WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | BS_TEXT, 333 | (width - cBTNwidth) / 2, height - cBTNheight - 5, 334 | cBTNwidth, cBTNheight, _hwnd, NULL, _hInst, NULL); 335 | 336 | HFONT hf = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); 337 | if (hf) 338 | { 339 | ::SendMessage(_hPText, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE, 0)); 340 | ::SendMessage(_hBtn, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE, 0)); 341 | } 342 | 343 | _hKeyHook = ::SetWindowsHookEx(WH_KEYBOARD, keyHookProc, _hInst, GetCurrentThreadId()); 344 | 345 | ::ShowWindow(_hwnd, SW_HIDE); 346 | 347 | ::SetTimer(_hwnd, 1, cInitialShowDelay_ms, NULL); 348 | 349 | return TRUE; 350 | } 351 | 352 | 353 | RECT ProgressDlg::adjustSizeAndPos(int width, int height) 354 | { 355 | RECT maxWin; 356 | maxWin.left = ::GetSystemMetrics(SM_XVIRTUALSCREEN); 357 | maxWin.top = ::GetSystemMetrics(SM_YVIRTUALSCREEN); 358 | maxWin.right = ::GetSystemMetrics(SM_CXVIRTUALSCREEN) + maxWin.left; 359 | maxWin.bottom = ::GetSystemMetrics(SM_CYVIRTUALSCREEN) + maxWin.top; 360 | 361 | POINT center; 362 | 363 | { 364 | RECT biasWin; 365 | ::GetWindowRect(nppData._nppHandle, &biasWin); 366 | center.x = (biasWin.left + biasWin.right) / 2; 367 | center.y = (biasWin.top + biasWin.bottom) / 2; 368 | } 369 | 370 | RECT win = maxWin; 371 | win.right = win.left + width; 372 | win.bottom = win.top + height; 373 | 374 | ::AdjustWindowRectEx(&win, (DWORD)::GetWindowLongPtr(_hwnd, GWL_STYLE), FALSE, 375 | (DWORD)::GetWindowLongPtr(_hwnd, GWL_EXSTYLE)); 376 | 377 | width = win.right - win.left; 378 | height = win.bottom - win.top; 379 | 380 | if (width < maxWin.right - maxWin.left) 381 | { 382 | win.left = center.x - width / 2; 383 | if (win.left < maxWin.left) 384 | win.left = maxWin.left; 385 | win.right = win.left + width; 386 | if (win.right > maxWin.right) 387 | { 388 | win.right = maxWin.right; 389 | win.left = win.right - width; 390 | } 391 | } 392 | else 393 | { 394 | win.left = maxWin.left; 395 | win.right = maxWin.right; 396 | } 397 | 398 | if (height < maxWin.bottom - maxWin.top) 399 | { 400 | win.top = center.y - height / 2; 401 | if (win.top < maxWin.top) 402 | win.top = maxWin.top; 403 | win.bottom = win.top + height; 404 | if (win.bottom > maxWin.bottom) 405 | { 406 | win.bottom = maxWin.bottom; 407 | win.top = win.bottom - height; 408 | } 409 | } 410 | else 411 | { 412 | win.top = maxWin.top; 413 | win.bottom = maxWin.bottom; 414 | } 415 | 416 | return win; 417 | } 418 | 419 | 420 | LRESULT CALLBACK ProgressDlg::keyHookProc(int code, WPARAM wParam, LPARAM lParam) 421 | { 422 | if (code >= 0 && Inst) 423 | { 424 | if (Inst->_hBtn == ::GetFocus()) 425 | { 426 | // Key is pressed 427 | if (!(lParam & (1 << 31))) 428 | { 429 | if (wParam == VK_RETURN || wParam == VK_ESCAPE) 430 | { 431 | Inst->cancel(); 432 | return 1; 433 | } 434 | } 435 | } 436 | } 437 | 438 | return ::CallNextHookEx(NULL, code, wParam, lParam); 439 | } 440 | 441 | 442 | LRESULT APIENTRY ProgressDlg::wndProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) 443 | { 444 | switch (umsg) 445 | { 446 | case WM_CREATE: 447 | return 0; 448 | 449 | case WM_SETFOCUS: 450 | ::SetFocus(Inst->_hBtn); 451 | return 0; 452 | 453 | case WM_COMMAND: 454 | if (HIWORD(wparam) == BN_CLICKED) 455 | { 456 | Inst->cancel(); 457 | return 0; 458 | } 459 | break; 460 | 461 | case WM_TIMER: 462 | Inst->Show(); 463 | return 0; 464 | 465 | case WM_DESTROY: 466 | ::PostQuitMessage(0); 467 | return 0; 468 | } 469 | 470 | return ::DefWindowProc(hwnd, umsg, wparam, lparam); 471 | } 472 | -------------------------------------------------------------------------------- /src/ProgressDlg/ProgressDlg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #pragma once 19 | 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | 30 | class ProgressDlg; 31 | using progress_ptr = std::shared_ptr; 32 | 33 | 34 | class ProgressDlg 35 | { 36 | public: 37 | static progress_ptr& Open(const TCHAR* info = NULL); 38 | 39 | static progress_ptr& Get() 40 | { 41 | return Inst; 42 | } 43 | 44 | static void Close() 45 | { 46 | Inst.reset(); 47 | } 48 | 49 | ~ProgressDlg(); 50 | 51 | inline void SetInfo(const TCHAR *info) const 52 | { 53 | ::SendMessage(_hPText, WM_SETTEXT, 0, (LPARAM)info); 54 | } 55 | 56 | void Show() const; 57 | 58 | bool IsCancelled() const; 59 | 60 | unsigned NextPhase(); 61 | bool SetMaxCount(intptr_t max, unsigned phase = 0); 62 | bool SetCount(intptr_t cnt, unsigned phase = 0); 63 | bool Advance(intptr_t cnt = 1, unsigned phase = 0); 64 | 65 | private: 66 | static const TCHAR cClassName[]; 67 | static const int cBackgroundColor; 68 | static const int cPBwidth; 69 | static const int cPBheight; 70 | static const int cBTNwidth; 71 | static const int cBTNheight; 72 | 73 | static const int cInitialShowDelay_ms = 500; 74 | 75 | static const int cPhases[]; 76 | 77 | static progress_ptr Inst; 78 | 79 | static DWORD WINAPI threadFunc(LPVOID data); 80 | static LRESULT CALLBACK keyHookProc(int code, WPARAM wParam, LPARAM lParam); 81 | static LRESULT APIENTRY wndProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam); 82 | 83 | ProgressDlg(); 84 | 85 | // Disable copy construction and operator= 86 | ProgressDlg(const ProgressDlg&); 87 | const ProgressDlg& operator=(const ProgressDlg&); 88 | 89 | HWND create(); 90 | void cancel(); 91 | void destroy(); 92 | 93 | inline void setPos(intptr_t pos) const 94 | { 95 | ::PostMessage(_hPBar, PBM_SETPOS, (WPARAM)pos, 0); 96 | } 97 | 98 | void update(); 99 | 100 | BOOL thread(); 101 | BOOL createProgressWindow(); 102 | RECT adjustSizeAndPos(int width, int height); 103 | 104 | HINSTANCE _hInst; 105 | volatile HWND _hwnd; 106 | HANDLE _hThread; 107 | HANDLE _hActiveState; 108 | HWND _hPText; 109 | HWND _hPBar; 110 | HWND _hBtn; 111 | HHOOK _hKeyHook; 112 | 113 | unsigned _phase; 114 | unsigned _phaseRange; 115 | unsigned _phasePosOffset; 116 | intptr_t _max; 117 | intptr_t _count; 118 | 119 | unsigned _pos; 120 | }; 121 | -------------------------------------------------------------------------------- /src/SQLite/SqliteHelper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C)2013 Jean-Sebastien Leroy (jean.sebastien.leroy@gmail.com) 4 | * Copyright (C)2017-2022 Pavel Nedev (pg.nedev@gmail.com) 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "SqliteHelper.h" 25 | #include "Tools.h" 26 | 27 | 28 | PSQLOPEN16 sqlite3_open16; 29 | PSQLPREPARE16V2 sqlite3_prepare16_v2; 30 | PSQLSTEP sqlite3_step; 31 | PSQLCOLUMNTEXT16 sqlite3_column_text16; 32 | PSQLFINALZE sqlite3_finalize; 33 | PSQLCLOSE sqlite3_close; 34 | 35 | 36 | namespace 37 | { 38 | 39 | inline bool getDllPath(TCHAR* dllPath, size_t bufLen) 40 | { 41 | HMODULE hPlugin = ::GetModuleHandle(TEXT("ComparePlus.dll")); 42 | if (!hPlugin) 43 | return false; 44 | 45 | ::GetModuleFileName(hPlugin, (LPWSTR)dllPath, (DWORD)bufLen); 46 | ::PathRemoveFileSpec(dllPath); 47 | _tcscat_s(dllPath, bufLen, TEXT("\\libs\\sqlite3.dll")); 48 | 49 | return true; 50 | } 51 | 52 | } 53 | 54 | 55 | bool isSQLlibFound() 56 | { 57 | TCHAR dllPath[MAX_PATH]; 58 | 59 | if (getDllPath(dllPath, _countof(dllPath))) 60 | return fileExists(dllPath); 61 | 62 | return false; 63 | } 64 | 65 | 66 | bool InitSQLite() 67 | { 68 | static bool isInit = false; 69 | 70 | if (!isInit) 71 | { 72 | TCHAR dllPath[MAX_PATH]; 73 | 74 | if (!getDllPath(dllPath, _countof(dllPath))) 75 | return false; 76 | 77 | HMODULE ligSQLite = ::LoadLibrary(dllPath); 78 | if (!ligSQLite) 79 | return false; 80 | 81 | sqlite3_open16 = (PSQLOPEN16)::GetProcAddress(ligSQLite, "sqlite3_open16"); 82 | if (!sqlite3_open16) 83 | return false; 84 | sqlite3_prepare16_v2 = (PSQLPREPARE16V2)::GetProcAddress(ligSQLite, "sqlite3_prepare16_v2"); 85 | if (!sqlite3_prepare16_v2) 86 | return false; 87 | sqlite3_step = (PSQLSTEP)::GetProcAddress(ligSQLite, "sqlite3_step"); 88 | if (!sqlite3_step) 89 | return false; 90 | sqlite3_column_text16 = (PSQLCOLUMNTEXT16)::GetProcAddress(ligSQLite, "sqlite3_column_text16"); 91 | if (!sqlite3_column_text16) 92 | return false; 93 | sqlite3_finalize = (PSQLFINALZE)::GetProcAddress(ligSQLite, "sqlite3_finalize"); 94 | if (!sqlite3_finalize) 95 | return false; 96 | sqlite3_close = (PSQLCLOSE)::GetProcAddress(ligSQLite, "sqlite3_close"); 97 | if (!sqlite3_close) 98 | return false; 99 | 100 | isInit = true; 101 | } 102 | 103 | return true; 104 | } 105 | -------------------------------------------------------------------------------- /src/SQLite/SqliteHelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C)2013 Jean-Sebastien Leroy (jean.sebastien.leroy@gmail.com) 4 | * Copyright (C)2017 Pavel Nedev (pg.nedev@gmail.com) 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #define sqlite3 HANDLE 23 | #define sqlite3_stmt HANDLE 24 | #define SQLITE_OK 0 25 | #define SQLITE_ROW 100 26 | 27 | 28 | typedef int (*PSQLOPEN16) (const void *filename, sqlite3 **ppDb); 29 | typedef int (*PSQLPREPARE16V2) (sqlite3 *db, const void *zSql, int nByte, sqlite3_stmt **ppStmt, const char **pzTail); 30 | typedef int (*PSQLSTEP) (sqlite3_stmt *pStmt); 31 | typedef const void * (*PSQLCOLUMNTEXT16) (sqlite3_stmt *pStmt, int iCol); 32 | typedef int (*PSQLFINALZE) (sqlite3_stmt *pStmt); 33 | typedef int (*PSQLCLOSE) (sqlite3 *db); 34 | 35 | 36 | extern PSQLOPEN16 sqlite3_open16; 37 | extern PSQLPREPARE16V2 sqlite3_prepare16_v2; 38 | extern PSQLSTEP sqlite3_step; 39 | extern PSQLCOLUMNTEXT16 sqlite3_column_text16; 40 | extern PSQLFINALZE sqlite3_finalize; 41 | extern PSQLCLOSE sqlite3_close; 42 | 43 | 44 | bool InitSQLite(); 45 | -------------------------------------------------------------------------------- /src/SettingsDlg/ColorCombo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Compare Plugin for Notepad++ 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include "ColorCombo.h" 19 | #include "resource.h" 20 | 21 | 22 | void ColorCombo::init(HINSTANCE hInst, HWND hNpp, HWND hCombo) 23 | { 24 | _hNpp = hNpp; 25 | Window::init(hInst, hNpp); 26 | 27 | /* subclass combo to get edit messages */ 28 | _comboBoxInfo.cbSize = sizeof(_comboBoxInfo); 29 | ::SendMessage(hCombo, CB_GETCOMBOBOXINFO, 0, (LPARAM)&_comboBoxInfo); 30 | ::SetWindowLongPtr(_comboBoxInfo.hwndItem, GWLP_USERDATA, reinterpret_cast(this)); 31 | _hDefaultComboProc = reinterpret_cast(::SetWindowLongPtr(_comboBoxInfo.hwndItem, GWLP_WNDPROC, reinterpret_cast(wndDefaultProc))); 32 | } 33 | 34 | 35 | LRESULT ColorCombo::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) 36 | { 37 | switch (Message) 38 | { 39 | case COLOR_POPUP_OK: 40 | { 41 | setColor((COLORREF)wParam); 42 | 43 | _pColorPopup->destroy(); 44 | delete _pColorPopup; 45 | _pColorPopup = NULL; 46 | 47 | return TRUE; 48 | } 49 | 50 | case WM_LBUTTONDOWN: 51 | case WM_LBUTTONDBLCLK: 52 | { 53 | RECT rc; 54 | POINT pt; 55 | ::GetWindowRect(hwnd, &rc); 56 | pt.x = rc.left; 57 | pt.y = rc.bottom; 58 | 59 | if (_pColorPopup == NULL) { 60 | _pColorPopup = new ColorPopup(_rgbCol); 61 | _pColorPopup->init(_hInst, hwnd, _hNpp); 62 | _pColorPopup->doDialog(pt); 63 | } 64 | 65 | return TRUE; 66 | } 67 | 68 | case COLOR_POPUP_CANCEL: 69 | case WM_DESTROY: 70 | { 71 | if (_pColorPopup != NULL) { 72 | _pColorPopup->destroy(); 73 | delete _pColorPopup; 74 | _pColorPopup = NULL; 75 | } 76 | 77 | break; 78 | } 79 | 80 | case WM_PAINT: 81 | { 82 | LRESULT lpRet = ::CallWindowProc(_hDefaultComboProc, hwnd, Message, wParam, lParam); 83 | DrawColor((HDC)wParam); 84 | 85 | return lpRet; 86 | } 87 | } 88 | 89 | return ::CallWindowProc(_hDefaultComboProc, hwnd, Message, wParam, lParam); 90 | } 91 | 92 | 93 | void ColorCombo::DrawColor(HDC hDcExt) 94 | { 95 | HDC hDc = NULL; 96 | HBRUSH hBrush = ::CreateSolidBrush(_rgbCol); 97 | 98 | if (hDcExt == NULL) { 99 | hDc = ::GetWindowDC(_comboBoxInfo.hwndCombo); 100 | } else { 101 | hDc = hDcExt; 102 | } 103 | 104 | /* draw item */ 105 | ::FillRect(hDc, &_comboBoxInfo.rcItem, hBrush); 106 | 107 | /* draw selection on focus */ 108 | if (_comboBoxInfo.hwndCombo == ::GetFocus()) 109 | { 110 | RECT rc = _comboBoxInfo.rcItem; 111 | ::InflateRect(&rc, -1, -1); 112 | ::DrawFocusRect(hDc, &rc); 113 | } 114 | 115 | ::DeleteObject(hBrush); 116 | 117 | if (hDcExt == NULL) { 118 | ::ReleaseDC(_comboBoxInfo.hwndCombo, hDc); 119 | } 120 | } 121 | 122 | 123 | -------------------------------------------------------------------------------- /src/SettingsDlg/ColorCombo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Compare Plugin for Notepad++ 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #pragma once 19 | 20 | 21 | #include "DockingFeature/Window.h" 22 | #include "ColorPopup.h" 23 | 24 | 25 | class ColorCombo : public Window 26 | { 27 | public : 28 | ColorCombo() : Window(), _rgbCol(0), _pColorPopup(NULL) 29 | { 30 | ::ZeroMemory(&_comboBoxInfo, sizeof(_comboBoxInfo)); 31 | }; 32 | 33 | ~ColorCombo () {}; 34 | virtual void init(HINSTANCE hInst, HWND hNpp, HWND hCombo); 35 | virtual void destroy() 36 | { 37 | ::DestroyWindow(_hSelf); 38 | }; 39 | 40 | void onSelect(void) 41 | { 42 | DrawColor(); 43 | }; 44 | 45 | void setColor(COLORREF rgbCol) 46 | { 47 | _rgbCol = rgbCol; 48 | ::RedrawWindow(_comboBoxInfo.hwndItem, &_comboBoxInfo.rcItem, NULL, RDW_INVALIDATE | RDW_UPDATENOW); 49 | }; 50 | 51 | void getColor(LPCOLORREF p_rgbCol) 52 | { 53 | if (p_rgbCol != NULL) { 54 | *p_rgbCol = _rgbCol; 55 | } 56 | }; 57 | 58 | private: 59 | void DrawColor(HDC hDcExt = NULL); 60 | 61 | private : 62 | HWND _hNpp; 63 | COMBOBOXINFO _comboBoxInfo; 64 | WNDPROC _hDefaultComboProc; 65 | 66 | COLORREF _rgbCol; 67 | ColorPopup* _pColorPopup; 68 | 69 | /* Subclassing combo boxes */ 70 | LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); 71 | 72 | static LRESULT CALLBACK wndDefaultProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) 73 | { 74 | return (((ColorCombo *)(::GetWindowLongPtr(hwnd, GWLP_USERDATA)))->runProc(hwnd, Message, wParam, lParam)); 75 | }; 76 | }; 77 | -------------------------------------------------------------------------------- /src/SettingsDlg/ColorPopup.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * this file is part of notepad++ 3 | * Copyright (C)2003 Don HO < donho@altern.org > 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either 8 | * version 2 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | */ 19 | 20 | #pragma comment (lib, "comdlg32") 21 | 22 | 23 | #include 24 | #include 25 | #include 26 | #include "ColorPopup.h" 27 | 28 | 29 | DWORD colorItems[] = { 30 | RGB( 0, 0, 0), RGB( 64, 0, 0), RGB(128, 0, 0), RGB(128, 64, 64), RGB(255, 0, 0), RGB(255, 128, 128), 31 | RGB(255, 255, 128), RGB(255, 255, 0), RGB(255, 128, 64), RGB(255, 128, 0), RGB(128, 64, 0), RGB(128, 128, 0), 32 | RGB(128, 128, 64), RGB( 0, 64, 0), RGB( 0, 128, 0), RGB( 0, 255, 0), RGB(128, 255, 0), RGB(128, 255, 128), 33 | RGB( 0, 255, 128), RGB( 0, 255, 64), RGB( 0, 128, 128), RGB( 0, 128, 64), RGB( 0, 64, 64), RGB(128, 128, 128), 34 | RGB( 64, 128, 128), RGB( 0, 0, 128), RGB( 0, 0, 255), RGB( 0, 64, 128), RGB( 0, 255, 255), RGB(128, 255, 255), 35 | RGB( 0, 128, 255), RGB( 0, 128, 192), RGB(128, 128, 255), RGB( 0, 0, 160), RGB( 0, 0, 64), RGB(192, 192, 192), 36 | RGB( 64, 0, 64), RGB( 64, 0, 64), RGB(128, 0, 128), RGB(128, 0, 64), RGB(128, 128, 192), RGB(255, 128, 192), 37 | RGB(255, 128, 255), RGB(255, 0, 255), RGB(255, 0, 128), RGB(128, 0, 255), RGB( 64, 0, 128), RGB(255, 255, 255), 38 | }; 39 | 40 | void ColorPopup::create(int dialogID) 41 | { 42 | _hSelf = ::CreateDialogParam(_hInst, MAKEINTRESOURCE(dialogID), _hParent, (DLGPROC)dlgProc, (LPARAM)this); 43 | 44 | Window::getClientRect(_rc); 45 | display(); 46 | } 47 | 48 | INT_PTR CALLBACK ColorPopup::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 49 | { 50 | switch (message) 51 | { 52 | case WM_MEASUREITEM: 53 | { 54 | RECT rc; 55 | LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT) lParam; 56 | ::GetWindowRect(::GetDlgItem(hwnd, lpmis->CtlID), &rc); 57 | lpmis->itemHeight = (rc.bottom-rc.top)/6; 58 | lpmis->itemWidth = (rc.right-rc.left)/8; 59 | return TRUE; 60 | } 61 | 62 | case WM_INITDIALOG : 63 | { 64 | ColorPopup *pColorPopup = (ColorPopup *)(lParam); 65 | pColorPopup->_hSelf = hwnd; 66 | ::SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); 67 | pColorPopup->run_dlgProc(message, wParam, lParam); 68 | return TRUE; 69 | } 70 | 71 | default : 72 | { 73 | ColorPopup *pColorPopup = reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); 74 | if (!pColorPopup) 75 | return FALSE; 76 | return pColorPopup->run_dlgProc(message, wParam, lParam); 77 | } 78 | } 79 | } 80 | 81 | INT_PTR CALLBACK ColorPopup::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) 82 | { 83 | switch (message) 84 | { 85 | case WM_INITDIALOG: 86 | { 87 | unsigned nColor; 88 | for (nColor = 0 ; nColor < _countof(colorItems); nColor++) 89 | { 90 | ::SendDlgItemMessage(_hSelf, IDC_COLOR_LIST, LB_ADDSTRING, nColor, (LPARAM)TEXT("")); 91 | ::SendDlgItemMessage(_hSelf, IDC_COLOR_LIST, LB_SETITEMDATA , nColor, (LPARAM)colorItems[nColor]); 92 | } 93 | 94 | return TRUE; 95 | } 96 | 97 | case WM_CTLCOLORLISTBOX: 98 | return (LRESULT) CreateSolidBrush(GetSysColor(COLOR_3DFACE)); 99 | 100 | case WM_DRAWITEM: 101 | { 102 | HDC hdc; 103 | COLORREF cr; 104 | HBRUSH hbrush; 105 | 106 | DRAWITEMSTRUCT *pdis = (DRAWITEMSTRUCT *)lParam; 107 | hdc = pdis->hDC; 108 | RECT rc = pdis->rcItem; 109 | 110 | // Transparent. 111 | SetBkMode(hdc,TRANSPARENT); 112 | 113 | // NULL object 114 | if (pdis->itemID == UINT(-1)) return 0; 115 | 116 | switch (pdis->itemAction) 117 | { 118 | case ODA_DRAWENTIRE: 119 | switch (pdis->CtlID) 120 | { 121 | case IDC_COLOR_LIST: 122 | rc = pdis->rcItem; 123 | cr = (COLORREF) pdis->itemData; 124 | InflateRect(&rc, -3, -3); 125 | hbrush = CreateSolidBrush((COLORREF)cr); 126 | FillRect(hdc, &rc, hbrush); 127 | DeleteObject(hbrush); 128 | FrameRect(hdc, &rc, (HBRUSH) GetStockObject(GRAY_BRUSH)); 129 | } 130 | // *** Intentional FALL THROUGH *** 131 | 132 | case ODA_SELECT: 133 | rc = pdis->rcItem; 134 | 135 | if (pdis->itemState & ODS_SELECTED) 136 | { 137 | rc.bottom --; 138 | rc.right --; 139 | // Draw the lighted side. 140 | HPEN hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW)); 141 | HPEN holdPen = (HPEN)SelectObject(hdc, hpen); 142 | MoveToEx(hdc, rc.left, rc.bottom, NULL); 143 | LineTo(hdc, rc.left, rc.top); 144 | LineTo(hdc, rc.right, rc.top); 145 | SelectObject(hdc, holdPen); 146 | DeleteObject(hpen); 147 | // Draw the darkened side. 148 | hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT)); 149 | holdPen = (HPEN)SelectObject(hdc, hpen); 150 | LineTo(hdc, rc.right, rc.bottom); 151 | LineTo(hdc, rc.left, rc.bottom); 152 | SelectObject(hdc, holdPen); 153 | DeleteObject(hpen); 154 | } 155 | else 156 | { 157 | hbrush = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); 158 | FrameRect(hdc, &rc, hbrush); 159 | DeleteObject(hbrush); 160 | } 161 | 162 | break; 163 | 164 | case ODA_FOCUS: 165 | rc = pdis->rcItem; 166 | InflateRect(&rc, -2, -2); 167 | DrawFocusRect(hdc, &rc); 168 | break; 169 | } 170 | 171 | return TRUE; 172 | } 173 | 174 | case WM_COMMAND: 175 | switch (LOWORD(wParam)) 176 | { 177 | case IDOK : 178 | { 179 | _isColorChooserLaunched = true; 180 | CHOOSECOLOR cc; // common dialog box structure 181 | static COLORREF acrCustClr[16] = { 182 | RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),\ 183 | RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),\ 184 | RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),\ 185 | RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),RGB(0xFF,0xFF,0xFF),\ 186 | }; // array of custom colors 187 | 188 | // Initialize CHOOSECOLOR 189 | ::ZeroMemory(&cc, sizeof(cc)); 190 | cc.lStructSize = sizeof(cc); 191 | cc.hwndOwner = _hParent; 192 | 193 | cc.lpCustColors = (LPDWORD) acrCustClr; 194 | cc.rgbResult = _color; 195 | cc.Flags = CC_FULLOPEN | CC_RGBINIT; 196 | 197 | display(false); 198 | 199 | if (ChooseColor(&cc) == TRUE) 200 | { 201 | ::SendMessage(_hParent, COLOR_POPUP_OK, cc.rgbResult, 0); 202 | } 203 | else 204 | { 205 | ::SendMessage(_hParent, COLOR_POPUP_CANCEL, 0, 0); 206 | } 207 | 208 | return TRUE; 209 | } 210 | 211 | case IDC_COLOR_LIST : 212 | { 213 | if (HIWORD(wParam) == LBN_SELCHANGE) 214 | { 215 | LRESULT i = ::SendMessage((HWND)lParam, LB_GETCURSEL, 0L, 0L); 216 | _color = static_cast(::SendMessage((HWND)lParam, LB_GETITEMDATA, i, 0L)); 217 | 218 | ::SendMessage(_hParent, COLOR_POPUP_OK, _color, 0); 219 | return TRUE; 220 | } 221 | 222 | return FALSE; 223 | } 224 | } 225 | 226 | return FALSE; 227 | 228 | case WM_ACTIVATE : 229 | { 230 | if (LOWORD(wParam) == WA_INACTIVE) 231 | if (!_isColorChooserLaunched) 232 | ::SendMessage(_hParent, COLOR_POPUP_CANCEL, 0, 0); 233 | 234 | return TRUE; 235 | } 236 | } 237 | 238 | return FALSE; 239 | } 240 | 241 | 242 | -------------------------------------------------------------------------------- /src/SettingsDlg/ColorPopup.h: -------------------------------------------------------------------------------- 1 | /* 2 | * this file is part of notepad++ 3 | * Copyright (C)2003 Don HO < donho@altern.org > 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either 8 | * version 2 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | */ 19 | 20 | 21 | #pragma once 22 | 23 | 24 | #include "DockingFeature/Window.h" 25 | #include "resource.h" 26 | 27 | class ColorPopup : public Window 28 | { 29 | public : 30 | ColorPopup() : Window(), _isColorChooserLaunched(false) {}; 31 | ColorPopup(COLORREF defaultColor) : Window(), _isColorChooserLaunched(false), _color(defaultColor) {}; 32 | ~ColorPopup(){}; 33 | 34 | void init(HINSTANCE hInst, HWND hParent, HWND hNpp) { 35 | _hNpp = hNpp; 36 | Window::init(hInst, hParent); 37 | } 38 | 39 | bool isCreated() const { 40 | return (_hSelf != NULL); 41 | }; 42 | 43 | void create(int dialogID); 44 | 45 | void doDialog(POINT p) { 46 | if (!isCreated()) 47 | create(IDD_COLOR_POPUP); 48 | ::SetWindowPos(_hSelf, HWND_TOP, p.x, p.y, _rc.right - _rc.left, _rc.bottom - _rc.top, SWP_SHOWWINDOW); 49 | }; 50 | 51 | virtual void destroy() { 52 | ::DestroyWindow(_hSelf); 53 | }; 54 | COLORREF getSelColor(){return _color;}; 55 | 56 | private : 57 | HWND _hNpp; 58 | RECT _rc; 59 | bool _isColorChooserLaunched; 60 | COLORREF _color; 61 | 62 | static INT_PTR CALLBACK dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 63 | INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); 64 | }; 65 | -------------------------------------------------------------------------------- /src/SettingsDlg/SettingsDialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #pragma once 19 | 20 | 21 | #include "PluginInterface.h" 22 | #include "DockingFeature/StaticDialog.h" 23 | #include "resource.h" 24 | #include "UserSettings.h" 25 | #include "ColorCombo.h" 26 | 27 | 28 | using namespace std; 29 | 30 | 31 | class SettingsDialog : public StaticDialog 32 | { 33 | 34 | public: 35 | SettingsDialog(HINSTANCE hInst, NppData nppDataParam) : StaticDialog() 36 | { 37 | _nppData = nppDataParam; 38 | Window::init(hInst, nppDataParam._nppHandle); 39 | }; 40 | 41 | ~SettingsDialog() 42 | { 43 | destroy(); 44 | } 45 | 46 | UINT doDialog(UserSettings* settings); 47 | 48 | virtual void destroy() {}; 49 | 50 | protected : 51 | INT_PTR CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam); 52 | 53 | void SetParams(UserSettings* settings = nullptr); 54 | void GetParams(); 55 | 56 | private: 57 | /* Handles */ 58 | NppData _nppData; 59 | 60 | // Combo color picker 61 | ColorCombo _ColorComboAdded; 62 | ColorCombo _ColorComboRemoved; 63 | ColorCombo _ColorComboMoved; 64 | ColorCombo _ColorComboChanged; 65 | ColorCombo _ColorComboAddHighlight; 66 | ColorCombo _ColorComboRemHighlight; 67 | 68 | struct UserSettings* _Settings; 69 | }; 70 | -------------------------------------------------------------------------------- /src/Tools.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C) 2016 Pavel Nedev (pg.nedev@gmail.com) 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include "Tools.h" 21 | 22 | 23 | std::map DelayedWork::workMap; 24 | 25 | 26 | bool DelayedWork::post(UINT delay_ms) 27 | { 28 | const bool isRunning = (_timerId != 0); 29 | 30 | _timerId = ::SetTimer(NULL, _timerId, delay_ms, timerCB); 31 | 32 | if (!isRunning && _timerId) 33 | workMap[_timerId] = this; 34 | 35 | return (_timerId != 0); 36 | } 37 | 38 | 39 | void DelayedWork::cancel() 40 | { 41 | if (_timerId) 42 | { 43 | ::KillTimer(NULL, _timerId); 44 | 45 | std::map::iterator it = workMap.find(_timerId); 46 | if (it != workMap.end()) 47 | workMap.erase(it); 48 | 49 | _timerId = 0; 50 | } 51 | } 52 | 53 | 54 | VOID CALLBACK DelayedWork::timerCB(HWND, UINT, UINT_PTR idEvent, DWORD) 55 | { 56 | std::map::iterator it = workMap.find(idEvent); 57 | 58 | ::KillTimer(NULL, idEvent); 59 | 60 | // Normally this shouldn't be the case 61 | if (it == workMap.end()) 62 | return; 63 | 64 | DelayedWork* work = it->second; 65 | workMap.erase(it); 66 | 67 | // This is not a valid case 68 | if (!work) 69 | return; 70 | 71 | work->_timerId = 0; 72 | (*work)(); 73 | } 74 | -------------------------------------------------------------------------------- /src/Tools.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C) 2016-2022 Pavel Nedev (pg.nedev@gmail.com) 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | 27 | /** 28 | * \struct 29 | * \brief 30 | */ 31 | template 32 | struct ScopedIncrementer 33 | { 34 | ScopedIncrementer(T& useCount) : _useCount(useCount) 35 | { 36 | ++_useCount; 37 | } 38 | 39 | ~ScopedIncrementer() 40 | { 41 | --_useCount; 42 | } 43 | 44 | ScopedIncrementer& operator=(const ScopedIncrementer&) = delete; 45 | 46 | private: 47 | T& _useCount; 48 | }; 49 | 50 | 51 | using ScopedIncrementerInt = ScopedIncrementer; 52 | 53 | 54 | /** 55 | * \class 56 | * \brief 57 | */ 58 | class DelayedWork 59 | { 60 | public: 61 | bool post(UINT delay_ms); 62 | void cancel(); 63 | 64 | bool isPending() const 65 | { 66 | return (_timerId != 0); 67 | } 68 | 69 | explicit operator bool() const 70 | { 71 | return (_timerId != 0); 72 | } 73 | 74 | bool operator!() const 75 | { 76 | return (_timerId == 0); 77 | } 78 | 79 | protected: 80 | DelayedWork() : _timerId(0) {} 81 | DelayedWork(const DelayedWork&) = delete; 82 | DelayedWork& operator=(const DelayedWork&) = delete; 83 | 84 | virtual ~DelayedWork() 85 | { 86 | cancel(); 87 | } 88 | 89 | virtual void operator()() = 0; 90 | 91 | UINT_PTR _timerId; 92 | 93 | private: 94 | static VOID CALLBACK timerCB(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime); 95 | 96 | static std::map workMap; 97 | }; 98 | 99 | 100 | inline void flushMsgQueue() 101 | { 102 | MSG msg; 103 | 104 | while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)); 105 | } 106 | 107 | 108 | inline bool fileExists(const TCHAR* filePath) 109 | { 110 | if (filePath == nullptr) 111 | return false; 112 | 113 | DWORD dwAttrib = ::GetFileAttributes(filePath); 114 | return (bool)(dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); 115 | } 116 | -------------------------------------------------------------------------------- /src/UserSettings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C)2017-2022 Pavel Nedev (pg.nedev@gmail.com) 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | 27 | // Those are interpreted as bool values 28 | #define DEFAULT_FIRST_IS_NEW 1 29 | #define DEFAULT_NEW_IN_SUB_VIEW 1 30 | #define DEFAULT_COMPARE_TO_PREV 1 31 | 32 | #define DEFAULT_ENCODINGS_CHECK 1 33 | #define DEFAULT_ALIGN_ALL_MATCHES 0 34 | #define DEFAULT_NEVER_MARK_IGNORED 0 35 | #define DEFAULT_FOLLOWING_CARET 1 36 | #define DEFAULT_WRAP_AROUND 0 37 | #define DEFAULT_GOTO_FIRST_DIFF 1 38 | #define DEFAULT_PROMPT_CLOSE_ON_MATCH 0 39 | 40 | #define DEFAULT_STATUS_INFO 0 41 | 42 | #define DEFAULT_ADDED_COLOR 0xC6FFC6 43 | #define DEFAULT_REMOVED_COLOR 0xC6C6FF 44 | #define DEFAULT_MOVED_COLOR 0xFFE6CC 45 | #define DEFAULT_CHANGED_COLOR 0x98E7E7 46 | #define DEFAULT_HIGHLIGHT_COLOR 0x0683FF 47 | #define DEFAULT_HIGHLIGHT_TRANSP 0 48 | #define DEFAULT_CARET_LINE_TRANSP 60 49 | 50 | #define DEFAULT_ADDED_COLOR_DARK 0x055A05 51 | #define DEFAULT_REMOVED_COLOR_DARK 0x16164F 52 | #define DEFAULT_MOVED_COLOR_DARK 0x4F361C 53 | #define DEFAULT_CHANGED_COLOR_DARK 0x145050 54 | #define DEFAULT_HIGHLIGHT_COLOR_DARK 0x0683FF 55 | #define DEFAULT_HIGHLIGHT_TRANSP_DARK 0 56 | #define DEFAULT_CARET_LINE_TRANSP_DARK 80 57 | 58 | #define DEFAULT_CHANGED_THRESHOLD 30 59 | 60 | #define DEFAULT_ENABLE_TOOLBAR_TB 1 61 | #define DEFAULT_SET_AS_FIRST_TB 1 62 | #define DEFAULT_COMPARE_TB 1 63 | #define DEFAULT_COMPARE_SEL_TB 1 64 | #define DEFAULT_CLEAR_COMPARE_TB 1 65 | #define DEFAULT_NAVIGATION_TB 1 66 | #define DEFAULT_SHOW_ONLY_DIFFS_TB 1 67 | #define DEFAULT_NAV_BAR_TB 1 68 | 69 | 70 | enum StatusType 71 | { 72 | DIFFS_SUMMARY = 0, 73 | COMPARE_OPTIONS, 74 | STATUS_DISABLED, 75 | STATUS_TYPE_END 76 | }; 77 | 78 | 79 | struct ColorSettings 80 | { 81 | int added; 82 | int removed; 83 | int changed; 84 | int moved; 85 | int blank; 86 | int _default; 87 | int add_highlight; 88 | int rem_highlight; 89 | int highlight_transparency; 90 | int caret_line_transparency; 91 | }; 92 | 93 | 94 | struct UserSettings 95 | { 96 | public: 97 | UserSettings() : _colors(&colorsLight) {} 98 | 99 | void load(); 100 | void save(); 101 | 102 | inline void markAsDirty() 103 | { 104 | dirty = true; 105 | } 106 | 107 | inline void useLightColors() 108 | { 109 | _colors = &colorsLight; 110 | } 111 | 112 | inline void useDarkColors() 113 | { 114 | _colors = &colorsDark; 115 | } 116 | 117 | inline ColorSettings& colors() 118 | { 119 | return *_colors; 120 | } 121 | 122 | static const TCHAR mainSection[]; 123 | 124 | static const TCHAR newFileViewSetting[]; 125 | static const TCHAR firstIsNewSetting[]; 126 | static const TCHAR compareToPrevSetting[]; 127 | 128 | static const TCHAR encodingsCheckSetting[]; 129 | static const TCHAR alignAllMatchesSetting[]; 130 | static const TCHAR markIgnoredLinesSetting[]; 131 | static const TCHAR followingCaretSetting[]; 132 | static const TCHAR wrapAroundSetting[]; 133 | static const TCHAR gotoFirstDiffSetting[]; 134 | static const TCHAR promptCloseOnMatchSetting[]; 135 | 136 | static const TCHAR detectMovesSetting[]; 137 | static const TCHAR detectCharDiffsSetting[]; 138 | static const TCHAR ignoreEmptyLinesSetting[]; 139 | static const TCHAR ignoreFoldedLinesSetting[]; 140 | static const TCHAR ignoreChangedSpacesSetting[]; 141 | static const TCHAR ignoreAllSpacesSetting[]; 142 | static const TCHAR ignoreCaseSetting[]; 143 | static const TCHAR ignoreRegexSetting[]; 144 | static const TCHAR invertRegexSetting[]; 145 | static const TCHAR ignoreRegexStrSetting[]; 146 | 147 | static const TCHAR showOnlySelSetting[]; 148 | static const TCHAR showOnlyDiffSetting[]; 149 | static const TCHAR navBarSetting[]; 150 | 151 | static const TCHAR reCompareOnChangeSetting[]; 152 | 153 | static const TCHAR statusInfoSetting[]; 154 | 155 | static const TCHAR colorsSection[]; 156 | 157 | static const TCHAR addedColorSetting[]; 158 | static const TCHAR removedColorSetting[]; 159 | static const TCHAR movedColorSetting[]; 160 | static const TCHAR changedColorSetting[]; 161 | static const TCHAR addHighlightColorSetting[]; 162 | static const TCHAR remHighlightColorSetting[]; 163 | static const TCHAR highlightTranspSetting[]; 164 | static const TCHAR caretLineTranspSetting[]; 165 | 166 | static const TCHAR addedColorDarkSetting[]; 167 | static const TCHAR removedColorDarkSetting[]; 168 | static const TCHAR movedColorDarkSetting[]; 169 | static const TCHAR changedColorDarkSetting[]; 170 | static const TCHAR addHighlightColorDarkSetting[]; 171 | static const TCHAR remHighlightColorDarkSetting[]; 172 | static const TCHAR highlightTranspDarkSetting[]; 173 | static const TCHAR caretLineTranspDarkSetting[]; 174 | 175 | static const TCHAR changedThresholdSetting[]; 176 | 177 | static const TCHAR toolbarSection[]; 178 | 179 | static const TCHAR enableToolbarSetting[]; 180 | static const TCHAR setAsFirstTBSetting[]; 181 | static const TCHAR compareTBSetting[]; 182 | static const TCHAR compareSelTBSetting[]; 183 | static const TCHAR clearCompareTBSetting[]; 184 | static const TCHAR navigationTBSetting[]; 185 | static const TCHAR showOnlyDiffsTBSetting[]; 186 | static const TCHAR navBarTBSetting[]; 187 | 188 | bool FirstFileIsNew; 189 | int NewFileViewId; 190 | bool CompareToPrev; 191 | 192 | bool EncodingsCheck; 193 | bool AlignAllMatches; 194 | bool NeverMarkIgnored; 195 | bool FollowingCaret; 196 | bool WrapAround; 197 | bool GotoFirstDiff; 198 | bool PromptToCloseOnMatch; 199 | 200 | bool DetectMoves; 201 | bool DetectCharDiffs; 202 | bool IgnoreEmptyLines; 203 | bool IgnoreFoldedLines; 204 | bool IgnoreChangedSpaces; 205 | bool IgnoreAllSpaces; 206 | bool IgnoreCase; 207 | bool IgnoreRegex; 208 | bool InvertRegex; 209 | std::wstring IgnoreRegexStr; 210 | 211 | bool ShowOnlyDiffs; 212 | bool ShowOnlySelections; 213 | bool UseNavBar; 214 | 215 | bool RecompareOnChange; 216 | StatusType StatusInfo; 217 | 218 | int ChangedThresholdPercent; 219 | 220 | bool EnableToolbar; 221 | bool SetAsFirstTB; 222 | bool CompareTB; 223 | bool CompareSelTB; 224 | bool ClearCompareTB; 225 | bool NavigationTB; 226 | bool ShowOnlyDiffsTB; 227 | bool NavBarTB; 228 | 229 | private: 230 | bool dirty {false}; 231 | 232 | ColorSettings colorsLight; 233 | ColorSettings colorsDark; 234 | 235 | ColorSettings* _colors; 236 | }; 237 | -------------------------------------------------------------------------------- /src/mingw-std-threads/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Mega Limited 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /src/mingw-std-threads/README.md: -------------------------------------------------------------------------------- 1 | mingw-std-threads 2 | ================= 3 | 4 | Implementation of standard C++11 threading classes, which are currently still missing on MinGW GCC. 5 | 6 | Target Windows version 7 | ---------------------- 8 | This implementation should work with Windows XP (regardless of service pack), or newer. 9 | The library automatically detects the version of Windows that is being targeted (at compile time), and selects an implementation that takes advantage of available Windows features. 10 | In MinGW GCC, the target Windows version may optionally be selected by the command-line option `-D _WIN32_WINNT=...`. 11 | Use `0x0600` for Windows Vista, or `0x0601` for Windows 7. 12 | See "[Modifying `WINVER` and `_WIN32_WINNT`](https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt)" for more details. 13 | 14 | Usage 15 | ----- 16 | 17 | This is a header-only library. To use, just include the corresponding `mingw.xxx.h file`, where `xxx` would be the name of the standard header that you would normally include. 18 | 19 | For example, `#include "mingw.thread.h"` replaces `#include `. 20 | 21 | Compatibility 22 | ------------- 23 | 24 | This code has been tested to work with MinGW-w64 5.3.0, but should work with any other MinGW version that has the `std` threading classes missing, has C++11 support for lambda functions, variadic templates, and has working mutex helper classes in ``. 25 | 26 | Switching from the win32-pthread based implementation 27 | ----------------------------------------------------- 28 | It seems that recent versions of MinGW-w64 include a Win32 port of pthreads, and have the `std::thread`, `std::mutex`, etc. classes implemented and working based on that compatibility 29 | layer. 30 | That is a somewhat heavier implementation, as it relies on an abstraction layer, so you may still want to use this implementation for efficiency purposes. 31 | Unfortunately you can't use this library standalone and independent of the system `` headers, as it relies on those headers for `std::unique_lock` and other non-trivial utility classes. 32 | In that case you will need to edit the `c++-config.h` file of your MinGW setup and comment out the definition of _GLIBCXX_HAS_GTHREADS. 33 | This will cause the system headers not to define the actual `thread`, `mutex`, etc. classes, but still define the necessary utility classes. 34 | 35 | Why MinGW has no threading classes 36 | ---------------------------------- 37 | It seems that for cross-platform threading implementation, the GCC standard library relies on the gthreads/pthreads library. 38 | If this library is not available, as is the case with MinGW, the classes `std::thread`, `std::mutex`, `std::condition_variable` are not defined. 39 | However, various usable helper classes are still defined in the system headers. 40 | Hence, this implementation does not re-define them, and instead includes those headers. 41 | 42 | -------------------------------------------------------------------------------- /src/mingw-std-threads/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(stdthreadtest) 2 | cmake_minimum_required(VERSION 2.8) 3 | 4 | add_definitions(-std=c++11 -Wall -Wextra) 5 | add_executable(${PROJECT_NAME} tests.cpp) 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of ComparePlus plugin for Notepad++ 3 | * Copyright (C)2011 Jean-Sebastien Leroy (jean.sebastien.leroy@gmail.com) 4 | * Copyright (C)2022-2024 Pavel Nedev (pg.nedev@gmail.com) 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #define PARAM_TO_STR(X) #X 23 | #define TO_STR(X) PARAM_TO_STR(X) 24 | 25 | 26 | #define VER_COPYRIGHT "Copyright (C) 2024\0" 27 | 28 | #define PLUGIN_VERSION 1.2.0 29 | #define VER_FILEVERSION 1,2,0,0 30 | #define IS_PRERELEASE 0 31 | 32 | #if (IS_PRERELEASE == 1) 33 | #define VER_PRERELEASE VS_FF_PRERELEASE 34 | #else 35 | #define VER_PRERELEASE 0 36 | #endif 37 | 38 | #ifdef _DEBUG 39 | #define VER_DEBUG VS_FF_DEBUG 40 | #else 41 | #define VER_DEBUG 0 42 | #endif 43 | 44 | #define VER_FILEFLAGS (VER_PRERELEASE | VER_DEBUG) 45 | 46 | #ifdef WIN64 47 | #define VER_PRODUCT_STR "ComparePlus (64-bit)\0" 48 | #else 49 | #define VER_PRODUCT_STR "ComparePlus (32-bit)\0" 50 | #endif 51 | 52 | 53 | #define IDDEFAULT 3 54 | #define IDD_ABOUT_DIALOG 101 55 | #define IDD_COLOR_POPUP 102 56 | #define IDD_SETTINGS_DIALOG 103 57 | #define IDD_COMPARE_OPTIONS_DIALOG 104 58 | #define IDD_NAV_DIALOG 105 59 | 60 | #define IDB_DOCKING_ICON 115 61 | 62 | #define IDB_SETFIRST 120 63 | #define IDB_SETFIRST_RTL 121 64 | #define IDB_COMPARE 122 65 | #define IDB_COMPARE_LINES 123 66 | #define IDB_CLEARCOMPARE 124 67 | #define IDB_FIRST 125 68 | #define IDB_LAST 126 69 | #define IDB_PREV 127 70 | #define IDB_NEXT 128 71 | #define IDB_DIFFS_ONLY 129 72 | #define IDB_NAVBAR 130 73 | 74 | #define IDB_SETFIRST_FL 140 75 | #define IDB_SETFIRST_RTL_FL 141 76 | #define IDB_COMPARE_FL 142 77 | #define IDB_COMPARE_LINES_FL 143 78 | #define IDB_CLEARCOMPARE_FL 144 79 | #define IDB_FIRST_FL 145 80 | #define IDB_LAST_FL 146 81 | #define IDB_PREV_FL 147 82 | #define IDB_NEXT_FL 148 83 | #define IDB_DIFFS_ONLY_FL 149 84 | #define IDB_NAVBAR_FL 150 85 | 86 | #define IDB_SETFIRST_FL_DM 160 87 | #define IDB_SETFIRST_RTL_FL_DM 161 88 | #define IDB_COMPARE_FL_DM 162 89 | #define IDB_COMPARE_LINES_FL_DM 163 90 | #define IDB_CLEARCOMPARE_FL_DM 164 91 | #define IDB_FIRST_FL_DM 165 92 | #define IDB_LAST_FL_DM 166 93 | #define IDB_PREV_FL_DM 167 94 | #define IDB_NEXT_FL_DM 168 95 | #define IDB_DIFFS_ONLY_FL_DM 169 96 | #define IDB_NAVBAR_FL_DM 170 97 | 98 | #define IDC_ABOUT_CLOSE_BUTTON 1001 99 | #define IDC_DONATE_BUTTON 1002 100 | #define IDC_COLOR_LIST 1003 101 | 102 | #define IDC_BUILD_TIME 1010 103 | #define IDC_EMAIL_LINK 1011 104 | #define IDC_REPO_URL 1012 105 | #define IDC_HELP_URL 1013 106 | 107 | #define IDC_NEW_IN_SUB 1020 108 | #define IDC_OLD_IN_SUB 1021 109 | #define IDC_FIRST_NEW 1022 110 | #define IDC_FIRST_OLD 1023 111 | #define IDC_COMPARE_TO_PREV 1024 112 | #define IDC_COMPARE_TO_NEXT 1025 113 | #define IDC_DIFFS_SUMMARY 1026 114 | #define IDC_COMPARE_OPTIONS 1027 115 | #define IDC_STATUS_DISABLED 1028 116 | #define IDC_ENCODING_CHECK 1029 117 | #define IDC_ALIGN_ALL_MATCHES 1030 118 | #define IDC_NEVER_MARK_IGNORED 1031 119 | #define IDC_PROMPT_CLOSE_ON_MATCH 1032 120 | #define IDC_WRAP_AROUND 1033 121 | #define IDC_GOTO_FIRST_DIFF 1034 122 | #define IDC_FOLLOWING_CARET 1035 123 | #define IDC_COMBO_ADDED_COLOR 1036 124 | #define IDC_COMBO_REMOVED_COLOR 1037 125 | #define IDC_COMBO_MOVED_COLOR 1038 126 | #define IDC_COMBO_CHANGED_COLOR 1039 127 | #define IDC_COMBO_ADD_HIGHLIGHT_COLOR 1040 128 | #define IDC_COMBO_REM_HIGHLIGHT_COLOR 1041 129 | #define IDC_HIGHLIGHT_SPIN_BOX 1042 130 | #define IDC_HIGHLIGHT_SPIN_CTL 1043 131 | #define IDC_CARET_LINE_SPIN_BOX 1044 132 | #define IDC_CARET_LINE_SPIN_CTL 1045 133 | #define IDC_THRESHOLD_SPIN_BOX 1046 134 | #define IDC_THRESHOLD_SPIN_CTL 1047 135 | #define IDC_ENABLE_TOOLBAR 1048 136 | #define IDC_SET_AS_FIRST_TB 1049 137 | #define IDC_COMPARE_TB 1050 138 | #define IDC_COMPARE_SELECTIONS_TB 1051 139 | #define IDC_CLEAR_COMPARE_TB 1052 140 | #define IDC_NAVIGATION_TB 1053 141 | #define IDC_SHOW_ONLY_DIFFS_TB 1054 142 | #define IDC_NAV_BAR_TB 1055 143 | 144 | #define IDC_DETECT_MOVES 1070 145 | #define IDC_DETECT_CHAR_DIFFS 1071 146 | #define IDC_IGNORE_EMPTY_LINES 1072 147 | #define IDC_IGNORE_FOLDED_LINES 1073 148 | #define IDC_IGNORE_CHANGED_SPACES 1074 149 | #define IDC_IGNORE_ALL_SPACES 1075 150 | #define IDC_IGNORE_CASE 1076 151 | #define IDC_IGNORE_REGEX 1077 152 | #define IDC_REGEX_MODE_IGNORE 1078 153 | #define IDC_REGEX_MODE_MATCH 1079 154 | #define IDC_IGNORE_REGEX_STR 1080 155 | 156 | #define IDC_STATIC -1 157 | 158 | #define COLOR_POPUP_OK 10000 159 | #define COLOR_POPUP_CANCEL 10001 160 | 161 | // Next default values for new objects 162 | // 163 | #ifdef APSTUDIO_INVOKED 164 | #ifndef APSTUDIO_READONLY_SYMBOLS 165 | #define _APS_NEXT_RESOURCE_VALUE 200 166 | #define _APS_NEXT_COMMAND_VALUE 20001 167 | #define _APS_NEXT_CONTROL_VALUE 1100 168 | #define _APS_NEXT_SYMED_VALUE 110 169 | #endif 170 | #endif 171 | --------------------------------------------------------------------------------